void X3fDecoder::decompressSigma( X3fImage &image ) { ByteStream input(mFile->getDataWrt(image.dataOffset), image.dataSize); mRaw->dim.x = image.width; mRaw->dim.y = image.height; mRaw->setCpp(3); mRaw->isCFA = false; mRaw->createData(); curr_image = ℑ int bits = 13; if (image.format == 35) { for (int i = 0; i < 3; i++) { planeDim[i].x = input.getShort(); planeDim[i].y = input.getShort(); } bits = 15; } if (image.format == 30 || image.format == 35) { for (int i = 0; i < 3; i++) pred[i] = input.getShort(); // Skip padding input.skipBytes(2); createSigmaTable(&input, bits); // Skip padding (2 x 0x00) if (image.format == 35) { input.skipBytes(2+4); plane_offset[0] = image.dataOffset + 68; } else { // Skip padding (2 x 0x00) input.skipBytes(2); plane_offset[0] = image.dataOffset + 48; } for (int i = 0; i < 3; i++) { plane_sizes[i] = input.getUInt(); // Planes are 16 byte aligned if (i != 2) { plane_offset[i+1] = plane_offset[i] + (((plane_sizes[i] + 15) / 16) * 16); if (plane_offset[i]>mFile->getSize()) ThrowRDE("SigmaDecompressor:Plane offset outside image"); } } mRaw->clearArea(iRectangle2D(0,0,image.width,image.height)); startTasks(3); //Interpolate based on blue value if (image.format == 35) { int w = planeDim[0].x; int h = planeDim[0].y; for (int i = 0; i < 2; i++) { for (int y = 0; y < h; y++) { ushort16* dst = (ushort16*)mRaw->getData(0, y * 2 )+ i; ushort16* dst_down = (ushort16*)mRaw->getData(0, y * 2 + 1) + i; ushort16* blue = (ushort16*)mRaw->getData(0, y * 2) + 2; ushort16* blue_down = (ushort16*)mRaw->getData(0, y * 2 + 1) + 2; for (int x = 0; x < w; x++) { // Interpolate 1 missing pixel int blue_mid = ((int)blue[0] + (int)blue[3] + (int)blue_down[0] + (int)blue_down[3] + 2)>>2; int avg = dst[0]; dst[0] = clampbits(((int)blue[0] - blue_mid) + avg, 16); dst[3] = clampbits(((int)blue[3] - blue_mid) + avg, 16); dst_down[0] = clampbits(((int)blue_down[0] - blue_mid) + avg, 16); dst_down[3] = clampbits(((int)blue_down[3] - blue_mid) + avg, 16); dst += 6; blue += 6; blue_down += 6; dst_down += 6; } } } } return; } // End if format 30
void NikonDecompressor::DecompressNikon(ByteStream *metadata, uint32 w, uint32 h, uint32 bitsPS, uint32 offset, uint32 size) { uint32 v0 = metadata->getByte(); uint32 v1 = metadata->getByte(); uint32 huffSelect = 0; uint32 split = 0; int pUp1[2]; int pUp2[2]; mUseBigtable = true; _RPT2(0, "Nef version v0:%u, v1:%u\n", v0, v1); if (v0 == 73 || v1 == 88) metadata->skipBytes(2110); if (v0 == 70) huffSelect = 2; if (bitsPS == 14) huffSelect += 3; pUp1[0] = metadata->getShort(); pUp1[1] = metadata->getShort(); pUp2[0] = metadata->getShort(); pUp2[1] = metadata->getShort(); int _max = 1 << bitsPS & 0x7fff; uint32 step = 0; uint32 csize = metadata->getShort(); if (csize > 1) step = _max / (csize - 1); if (v0 == 68 && v1 == 32 && step > 0 && !uncorrectedRawValues) { for (uint32 i = 0; i < csize; i++) curve[i*step] = metadata->getShort(); for (int i = 0; i < _max; i++) curve[i] = (curve[i-i%step] * (step - i % step) + curve[i-i%step+step] * (i % step)) / step; metadata->setAbsoluteOffset(562); split = metadata->getShort(); } else if (v0 != 70 && csize <= 0x4001 && !uncorrectedRawValues) { for (uint32 i = 0; i < csize; i++) { curve[i] = metadata->getShort(); } _max = csize; } initTable(huffSelect); mRaw->whitePoint = curve[_max-1]; mRaw->blackLevel = curve[0]; ushort16 top = mRaw->whitePoint; for (int i = _max; i < 0x8000; i++) curve[i] = top; uint32 x, y; BitPumpMSB bits(mFile->getData(offset), size); uchar8 *draw = mRaw->getData(); uint32 *dest; uint32 pitch = mRaw->pitch; int pLeft1 = 0; int pLeft2 = 0; uint32 cw = w / 2; for (y = 0; y < h; y++) { if (split && y == split) { initTable(huffSelect + 1); } dest = (uint32*) & draw[y*pitch]; // Adjust destination pUp1[y&1] += HuffDecodeNikon(bits); pUp2[y&1] += HuffDecodeNikon(bits); pLeft1 = pUp1[y&1]; pLeft2 = pUp2[y&1]; dest[0] = curve[clampbits(pLeft1,15)] | ((uint32)curve[clampbits(pLeft2,15)] << 16); for (x = 1; x < cw; x++) { bits.checkPos(); pLeft1 += HuffDecodeNikon(bits); pLeft2 += HuffDecodeNikon(bits); dest[x] = curve[clampbits(pLeft1,15)] | ((uint32)curve[clampbits(pLeft2,15)] << 16); } } }