in dmg/io.c [303:391]
void extractBLKX(AbstractFile* in, AbstractFile* out, BLKXTable* blkx) {
unsigned char* inBuffer;
unsigned char* outBuffer;
unsigned char zero;
size_t bufferSize;
size_t have;
size_t expectedSize;
off_t initialOffset;
int i;
int ret;
uint32_t type;
bufferSize = SECTOR_SIZE * blkx->decompressBufferRequested;
ASSERT(inBuffer = (unsigned char*) malloc(bufferSize), "malloc");
initialOffset = out->tell(out);
ASSERT(initialOffset != -1, "ftello");
zero = 0;
for(i = 0; i < blkx->blocksRunCount; i++) {
ASSERT(in->seek(in, blkx->dataStart + blkx->runs[i].compOffset) == 0, "fseeko");
ASSERT(out->seek(out, initialOffset + (blkx->runs[i].sectorStart * SECTOR_SIZE)) == 0, "mSeek");
if(blkx->runs[i].sectorCount > 0) {
ASSERT(out->seek(out, initialOffset + (blkx->runs[i].sectorStart + blkx->runs[i].sectorCount) * SECTOR_SIZE - 1) == 0, "mSeek");
ASSERT(out->write(out, &zero, 1) == 1, "mWrite");
ASSERT(out->seek(out, initialOffset + (blkx->runs[i].sectorStart * SECTOR_SIZE)) == 0, "mSeek");
}
if(blkx->runs[i].type == BLOCK_TERMINATOR) {
break;
}
if( blkx->runs[i].compLength == 0) {
continue;
}
printf("run %d: start=%" PRId64 " sectors=%" PRId64 ", length=%" PRId64 ", fileOffset=0x%" PRIx64 "\n", i, initialOffset + (blkx->runs[i].sectorStart * SECTOR_SIZE), blkx->runs[i].sectorCount, blkx->runs[i].compLength, blkx->runs[i].compOffset);
switch(blkx->runs[i].type) {
case BLOCK_RAW:
if(blkx->runs[i].compLength > bufferSize) {
uint64_t left = blkx->runs[i].compLength;
void* pageBuffer = malloc(DEFAULT_BUFFER_SIZE);
while(left > 0) {
size_t thisRead;
if(left > DEFAULT_BUFFER_SIZE) {
thisRead = DEFAULT_BUFFER_SIZE;
} else {
thisRead = left;
}
ASSERT((have = in->read(in, pageBuffer, thisRead)) == thisRead, "fread");
ASSERT(out->write(out, pageBuffer, have) == have, "mWrite");
left -= have;
}
free(pageBuffer);
} else {
ASSERT((have = in->read(in, inBuffer, blkx->runs[i].compLength)) == blkx->runs[i].compLength, "fread");
ASSERT(out->write(out, inBuffer, have) == have, "mWrite");
}
break;
case BLOCK_IGNORE:
break;
case BLOCK_COMMENT:
break;
case BLOCK_TERMINATOR:
break;
default:
type = blkx->runs[i].type;
if (compressionBlockTypeSupported(type) != 0) {
fprintf(stderr, "Unsupported block type %#08x\n", type);
exit(1);
}
expectedSize = blkx->runs[i].sectorCount * SECTOR_SIZE;
ASSERT(outBuffer = (unsigned char*)malloc(expectedSize), "malloc");
ASSERT(in->read(in, inBuffer, blkx->runs[i].compLength) == blkx->runs[i].compLength, "fread");
ASSERT(decompressRun(type, inBuffer, blkx->runs[i].compLength, outBuffer, expectedSize) == 0,
"decompression failed");
ASSERT(out->write(out, outBuffer, expectedSize) == expectedSize, "mWrite");
free(outBuffer);
}
}
free(inBuffer);
}