Пример #1
0
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
Пример #2
0
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);
    }
  }
}