Beispiel #1
0
void NefDecoder::decodeMetaDataInternal(CameraMetaData *meta) {
  int iso = 0;
  mRaw->cfa.setCFA(CFA_RED, CFA_GREEN, CFA_GREEN2, CFA_BLUE);

  vector<TiffIFD*> data = mRootIFD->getIFDsWithTag(MODEL);

  if (data.empty())
    ThrowRDE("NEF Meta Decoder: Model name found");
  if (!data[0]->hasEntry(MAKE))
    ThrowRDE("NEF Support: Make name not found");

  int white = mRaw->whitePoint;
  int black = mRaw->blackLevel;

  string make = data[0]->getEntry(MAKE)->getString();
  string model = data[0]->getEntry(MODEL)->getString();

  if (mRootIFD->hasEntryRecursive(ISOSPEEDRATINGS))
    iso = mRootIFD->getEntryRecursive(ISOSPEEDRATINGS)->getInt();

  string mode = getMode();
  if (meta->hasCamera(make, model, mode)) {
    setMetaData(meta, make, model, mode, iso);
  } else {
    setMetaData(meta, make, model, "", iso);
  }

  if (white != 65536)
    mRaw->whitePoint = white;
  if (black >= 0)
    mRaw->blackLevel = black;
}
void PentaxDecompressor::decompress(const ByteStream& data) const {
  BitPumpMSB bs(data);
  uchar8* draw = mRaw->getData();

  assert(mRaw->dim.y > 0);
  assert(mRaw->dim.x > 0);
  assert(mRaw->dim.x % 2 == 0);

  int pUp1[2] = {0, 0};
  int pUp2[2] = {0, 0};

  for (int y = 0; y < mRaw->dim.y && mRaw->dim.x >= 2; y++) {
    auto* dest = reinterpret_cast<ushort16*>(&draw[y * mRaw->pitch]);

    pUp1[y & 1] += ht.decodeNext(bs);
    pUp2[y & 1] += ht.decodeNext(bs);

    int pLeft1 = dest[0] = pUp1[y & 1];
    int pLeft2 = dest[1] = pUp2[y & 1];

    for (int x = 2; x < mRaw->dim.x; x += 2) {
      pLeft1 += ht.decodeNext(bs);
      pLeft2 += ht.decodeNext(bs);

      dest[x] = pLeft1;
      dest[x + 1] = pLeft2;

      if (pLeft1 < 0 || pLeft1 > 65535)
        ThrowRDE("decoded value out of bounds at %d:%d", x, y);
      if (pLeft2 < 0 || pLeft2 > 65535)
        ThrowRDE("decoded value out of bounds at %d:%d", x, y);
    }
  }
}
Beispiel #3
0
void NefDecoder::readCoolpixMangledRaw(ByteStream &input, iPoint2D& size, iPoint2D& offset, int inputPitch) {
  uchar8* data = mRaw->getData();
  uint32 outPitch = mRaw->pitch;
  uint32 w = size.x;
  uint32 h = size.y;
  uint32 cpp = mRaw->getCpp();
  if (input.getRemainSize() < (inputPitch*h)) {
    if ((int)input.getRemainSize() > inputPitch)
      h = input.getRemainSize() / inputPitch - 1;
    else
      ThrowIOE("readUncompressedRaw: Not enough data to decode a single line. Image file truncated.");
  }

  if (offset.y > mRaw->dim.y)
    ThrowRDE("readUncompressedRaw: Invalid y offset");
  if (offset.x + size.x > mRaw->dim.x)
    ThrowRDE("readUncompressedRaw: Invalid x offset");

  uint32 y = offset.y;
  h = MIN(h + (uint32)offset.y, (uint32)mRaw->dim.y);
  w *= cpp;
  BitPumpMSB32 *in = new BitPumpMSB32(&input);
  for (; y < h; y++) {
    ushort16* dest = (ushort16*) & data[offset.x*sizeof(ushort16)*cpp+y*outPitch];
    for (uint32 x = 0 ; x < w; x++) {
      dest[x] =  in->getBits(12);
    }
  }
}
Beispiel #4
0
void X3fParser::readDirectory()
{
  bytes->setAbsoluteOffset(mFile->getSize()-4);
  uint32 dir_off = bytes->getUInt();
  bytes->setAbsoluteOffset(dir_off);

  // Check signature
  if (0 != getIdAsString(bytes).compare("SECd"))
    ThrowRDE("X3F Decoder: Unable to locate directory");

  uint32 version = bytes->getUInt();
  if (version < 0x00020000)
    ThrowRDE("X3F Decoder: File version too old (directory)");

  uint32 n_entries = bytes->getUInt();
  for (uint32 i = 0; i < n_entries; i++) {
    X3fDirectory dir(bytes);
    decoder->mDirectory.push_back(dir);
    bytes->pushOffset();
    if (0 == dir.id.compare("IMA2") || 0 == dir.id.compare("IMAG")){
      decoder->mImages.push_back(X3fImage(bytes, dir.offset, dir.length));
    }
    if (0 == dir.id.compare("PROP")){
      decoder->mProperties.addProperties(bytes, dir.offset, dir.length);
    }
    bytes->popOffset();
  }
}
// Interpolate and convert sRaw data.
void Cr2Decoder::sRawInterpolate() {
  vector<TiffIFD*> data = mRootIFD->getIFDsWithTag((TiffTag)0x4001);
  if (data.empty())
    ThrowRDE("CR2 sRaw: Unable to locate WB info.");

  const ushort16 *wb_data = data[0]->getEntry((TiffTag)0x4001)->getShortArray();

  // Offset to sRaw coefficients used to reconstruct uncorrected RGB data.
  wb_data = &wb_data[4+(126+22)/2];

  sraw_coeffs[0] = wb_data[0];
  sraw_coeffs[1] = (wb_data[1] + wb_data[2] + 1) >> 1;
  sraw_coeffs[2] = wb_data[3];

  // Check if sRaw2 is using old coefficients
  data = mRootIFD->getIFDsWithTag(MODEL);

  if (data.empty())
    ThrowRDE("CR2 sRaw Decoder: Model name not found");

  string model = data[0]->getEntry(MODEL)->getString();
  bool isOldSraw = (model.compare("Canon EOS 40D") == 0);

  if (mRaw->subsampling.y == 1 && mRaw->subsampling.x == 2) {
    if (isOldSraw)
      interpolate_422_old(mRaw->dim.x / 2, mRaw->dim.y , 0, mRaw->dim.y);
    else
      interpolate_422(mRaw->dim.x / 2, mRaw->dim.y , 0, mRaw->dim.y);
  } else {
    interpolate_420(mRaw->dim.x / 2, mRaw->dim.y / 2 , 0 , mRaw->dim.y / 2);
  }
}
Beispiel #6
0
RawImage MrwDecoder::decodeRawInternal() {
  uint32 imgsize;

  mRaw->dim = iPoint2D(raw_width, raw_height);
  mRaw->createData();

  if (packed)
    imgsize = raw_width * raw_height * 3 / 2;
  else
    imgsize = raw_width * raw_height * 2;

  if (!mFile->isValid(data_offset))
    ThrowRDE("MRW decoder: Data offset after EOF, file probably truncated");
  if (!mFile->isValid(data_offset+imgsize-1))
    ThrowRDE("MRW decoder: Image end after EOF, file probably truncated");

  ByteStream input(mFile->getData(data_offset), imgsize);
 
  try {
    if (packed)
      Decode12BitRawBE(input, raw_width, raw_height);
    else
      Decode12BitRawBEunpacked(input, raw_width, raw_height);
  } catch (IOException &e) {
    mRaw->setError(e.what());
    // Let's ignore it, it may have delivered somewhat useful data.
  }

  return mRaw;
}
  void RawImageDataFloat::calculateBlackAreas() {
    float accPixels[4] = {0,0,0,0};
    int totalpixels = 0;

    for (uint32 i = 0; i < blackAreas.size(); i++) {
      BlackArea area = blackAreas[i];

      /* Make sure area sizes are multiple of two, 
      so we have the same amount of pixels for each CFA group */
      area.size = area.size - (area.size&1);

      /* Process horizontal area */
      if (!area.isVertical) {
        if ((int)area.offset+(int)area.size > uncropped_dim.y)
          ThrowRDE("RawImageData::calculateBlackAreas: Offset + size is larger than height of image");
        for (uint32 y = area.offset; y < area.offset+area.size; y++) {
          float *pixel = (float*)getDataUncropped(mOffset.x, y);
          for (int x = mOffset.x; x < dim.x+mOffset.x; x++) {
            accPixels[((y&1)<<1)|(x&1)] += *pixel++;
          }
        }
        totalpixels += area.size * dim.x;
      }

      /* Process vertical area */
      if (area.isVertical) {
        if ((int)area.offset+(int)area.size > uncropped_dim.x)
          ThrowRDE("RawImageData::calculateBlackAreas: Offset + size is larger than width of image");
        for (int y = mOffset.y; y < dim.y+mOffset.y; y++) {
          float *pixel = (float*)getDataUncropped(area.offset, y);
          for (uint32 x = area.offset; x < area.size+area.offset; x++) {
            accPixels[((y&1)<<1)|(x&1)] += *pixel++;
          }
        }
        totalpixels += area.size * dim.y;
      }
    }

    if (!totalpixels) {
      for (int i = 0 ; i < 4; i++)
        blackLevelSeparate[i] = blackLevel;
      return;
    }

    /* Calculate median value of black areas for each component */
    /* Adjust the number of total pixels so it is the same as the median of each histogram */
    totalpixels /= 4;

    for (int i = 0 ; i < 4; i++) {
      blackLevelSeparate[i] = (int)(65535.0f * accPixels[i]/totalpixels);
    }

    /* If this is not a CFA image, we do not use separate blacklevels, use average */
    if (!isCFA) {
      int total = 0;
      for (int i = 0 ; i < 4; i++)
        total+=blackLevelSeparate[i];
      for (int i = 0 ; i < 4; i++)
        blackLevelSeparate[i] = (total+2)>>2;
    }
Beispiel #8
0
RawImage CrwDecoder::decodeRawInternal() {
    CiffEntry *sensorInfo = mRootIFD->getEntryRecursive(CIFF_SENSORINFO);

    if (!sensorInfo || sensorInfo->count < 6 || sensorInfo->type != CIFF_SHORT)
        ThrowRDE("CRW: Couldn't find image sensor info");

    uint32 width = sensorInfo->getShort(1);
    uint32 height = sensorInfo->getShort(2);

    CiffEntry *decTable = mRootIFD->getEntryRecursive(CIFF_DECODERTABLE);
    if (!decTable || decTable->type != CIFF_LONG)
        ThrowRDE("CRW: Couldn't find decoder table");

    uint32 dec_table = decTable->getInt();
    if (dec_table > 2)
        ThrowRDE("CRW: Unknown decoder table %d", dec_table);

    mRaw->dim = iPoint2D(width, height);
    mRaw->createData();

    bool lowbits = hints.find("no_decompressed_lowbits") == hints.end();
    decodeRaw(lowbits, dec_table, width, height);

    return mRaw;
}
Beispiel #9
0
RawImage KdcDecoder::decodeRawInternal() {
  int compression = mRootIFD->getEntryRecursive(COMPRESSION)->getInt();
  if (7 != compression)
    ThrowRDE("KDC Decoder: Unsupported compression %d", compression);

  TiffEntry *ex = mRootIFD->getEntryRecursive(PIXELXDIMENSION);
  TiffEntry *ey = mRootIFD->getEntryRecursive(PIXELYDIMENSION);

  if (NULL == ex || NULL == ey)
    ThrowRDE("KDC Decoder: Unable to retrieve image size");

  uint32 width = ex->getInt();
  uint32 height = ey->getInt();

  TiffEntry *offset = mRootIFD->getEntryRecursive(KODAK_KDC_OFFSET);
  if (!offset || offset->count < 13)
    ThrowRDE("KDC Decoder: Couldn't find the KDC offset");
  const uint32 *offsetarray = offset->getIntArray();
  uint32 off = offsetarray[4] + offsetarray[12];

  mRaw->dim = iPoint2D(width, height);
  mRaw->createData();
  ByteStream input(mFile->getData(off), mFile->getSize()-off);

  Decode12BitRawBE(input, width, height);

  return mRaw;
}
Beispiel #10
0
void ColorFilterArray::setColorAt(iPoint2D pos, CFAColor c) {
  if (pos.x > 1 || pos.x < 0)
    ThrowRDE("ColorFilterArray::SetColor: position out of CFA pattern");
  if (pos.y > 1 || pos.y < 0)
    ThrowRDE("ColorFilterArray::SetColor: position out of CFA pattern");
  cfa[pos.x+pos.y*2] = c;
//  _RPT2(0, "cfa[%u] = %u\n",pos.x+pos.y*2, c);
}
Beispiel #11
0
RawImage MosDecoder::decodeRawInternal() {
  vector<TiffIFD*> data;
  TiffIFD* raw = NULL;
  uint32 off = 0;

  uint32 base = 8;
  // We get a pointer up to the end of the file as we check offset bounds later
  const uchar8 *insideTiff = mFile->getData(base, mFile->getSize()-base);
  if (get4LE(insideTiff, 0) == 0x49494949) {
    uint32 offset = get4LE(insideTiff, 8);
    if (offset+base+4 > mFile->getSize())
      ThrowRDE("MOS: PhaseOneC offset out of bounds");

    uint32 entries = get4LE(insideTiff, offset);
    uint32 pos = 8; // Skip another 4 bytes

    uint32 width=0, height=0, strip_offset=0, data_offset=0, wb_offset=0;
    while (entries--) {
      if (offset+base+pos+16 > mFile->getSize())
        ThrowRDE("MOS: PhaseOneC offset out of bounds");

      uint32 tag  = get4LE(insideTiff, offset+pos);
      //uint32 type = get4LE(insideTiff, offset+pos+4);
      //uint32 len  = get4LE(insideTiff, offset+pos+8);
      uint32 data = get4LE(insideTiff, offset+pos+12);
      pos += 16;
      switch(tag) {
      case 0x107: wb_offset    = data+base;      break;
      case 0x108: width        = data;      break;
      case 0x109: height       = data;      break;
      case 0x10f: data_offset  = data+base; break;
      case 0x21c: strip_offset = data+base; break;
      case 0x21d: black_level  = data>>2;   break;
      }
    }
    if (width <= 0 || height <= 0)
      ThrowRDE("MOS: PhaseOneC couldn't find width and height");
    if (strip_offset+height*4 > mFile->getSize())
      ThrowRDE("MOS: PhaseOneC strip offsets out of bounds");
    if (data_offset > mFile->getSize())
      ThrowRDE("MOS: PhaseOneC data offset out of bounds");

    mRaw->dim = iPoint2D(width, height);
    mRaw->createData();

    DecodePhaseOneC(data_offset, strip_offset, width, height);

    const uchar8 *data = mFile->getData(wb_offset, 12);
    for(int i=0; i<3; i++) {
      // Use get4LE instead of going straight to float so this is endian clean
      uint32 value = get4LE(data, i*4);
      mRaw->metadata.wbCoeffs[i] = *((float *) &value);
    }

    return mRaw;
  } else {
Beispiel #12
0
void SrwDecoder::checkSupportInternal(CameraMetaData *meta) {
  vector<TiffIFD*> data = mRootIFD->getIFDsWithTag(MODEL);
  if (data.empty())
    ThrowRDE("Srw Support check: Model name found");
  if (!data[0]->hasEntry(MAKE))
    ThrowRDE("SRW Support: Make name not found");
  string make = data[0]->getEntry(MAKE)->getString();
  string model = data[0]->getEntry(MODEL)->getString();
  this->checkCameraSupported(meta, make, model, "");
}
Beispiel #13
0
RawImage NakedDecoder::decodeRawInternal() {
  uint32 width=0, height=0, filesize=0, bits=0, offset=0;
  if(cam->hints.find("full_width") != cam->hints.end()) {
    string tmp = cam->hints.find(string("full_width"))->second;
    width = (uint32) atoi(tmp.c_str());
  } else
    ThrowRDE("Naked: couldn't find width");

  if(cam->hints.find("full_height") != cam->hints.end()) {
    string tmp = cam->hints.find(string("full_height"))->second;
    height = (uint32) atoi(tmp.c_str());
  } else
    ThrowRDE("Naked: couldn't find height");

  if(cam->hints.find("filesize") != cam->hints.end()) {
    string tmp = cam->hints.find(string("filesize"))->second;
    filesize = (uint32) atoi(tmp.c_str());
  } else
    ThrowRDE("Naked: couldn't find filesize");

  if(cam->hints.find("offset") != cam->hints.end()) {
    string tmp = cam->hints.find(string("offset"))->second;
    offset = (uint32) atoi(tmp.c_str());
  }

  if(cam->hints.find("bits") != cam->hints.end()) {
    string tmp = cam->hints.find(string("bits"))->second;
    bits = (uint32) atoi(tmp.c_str());
  } else
    bits = (filesize-offset)*8/width/height;

  BitOrder bo = BitOrder_Jpeg16;  // Default
  if(cam->hints.find("order") != cam->hints.end()) {
    string tmp = cam->hints.find(string("order"))->second;
    if (tmp.compare("plain") == 0) {
      bo = BitOrder_Plain;
    } else if (tmp.compare("jpeg") == 0) {
      bo = BitOrder_Jpeg;
    } else if (tmp.compare("jpeg16") == 0) {
      bo = BitOrder_Jpeg16;    
    } else if (tmp.compare("jpeg32") == 0) {
      bo = BitOrder_Jpeg32;    
    }
  }

  mRaw->dim = iPoint2D(width, height);
  mRaw->createData();

  ByteStream input(mFile->getData(offset), mFile->getSize()-offset);
  iPoint2D pos(0, 0);
  readUncompressedRaw(input, mRaw->dim, pos, width*bits/8, bits, bo);

  return mRaw;
}
Beispiel #14
0
void CrwDecoder::checkSupportInternal(CameraMetaData *meta) {
    vector<CiffIFD*> data = mRootIFD->getIFDsWithTag(CIFF_MAKEMODEL);
    if (data.empty())
        ThrowRDE("CRW Support check: Model name not found");
    vector<string> makemodel = data[0]->getEntry(CIFF_MAKEMODEL)->getStrings();
    if (makemodel.size() < 2)
        ThrowRDE("CRW Support check: wrong number of strings for make/model");
    string make = makemodel[0];
    string model = makemodel[1];

    this->checkCameraSupported(meta, make, model, "");
}
Beispiel #15
0
void KdcDecoder::decodeMetaDataInternal(CameraMetaData *meta) {
  vector<TiffIFD*> data = mRootIFD->getIFDsWithTag(MODEL);

  if (data.empty())
    ThrowRDE("KDC Decoder: Model name found");
  if (!data[0]->hasEntry(MAKE))
    ThrowRDE("KDC Decoder: Make name not found");

  string make = data[0]->getEntry(MAKE)->getString();
  string model = data[0]->getEntry(MODEL)->getString();
  setMetaData(meta, make, model, "", 0);
}
Beispiel #16
0
void CrwDecoder::decodeMetaDataInternal(CameraMetaData *meta) {
    int iso = 0;
    mRaw->cfa.setCFA(iPoint2D(2,2), CFA_RED, CFA_GREEN, CFA_GREEN2, CFA_BLUE);
    vector<CiffIFD*> data = mRootIFD->getIFDsWithTag(CIFF_MAKEMODEL);
    if (data.empty())
        ThrowRDE("CRW Support check: Model name not found");
    vector<string> makemodel = data[0]->getEntry(CIFF_MAKEMODEL)->getStrings();
    if (makemodel.size() < 2)
        ThrowRDE("CRW Support check: wrong number of strings for make/model");
    string make = makemodel[0];
    string model = makemodel[1];
    string mode = "";

    if (mRootIFD->hasEntryRecursive(CIFF_SHOTINFO)) {
        CiffEntry *shot_info = mRootIFD->getEntryRecursive(CIFF_SHOTINFO);
        if (shot_info->type == CIFF_SHORT && shot_info->count >= 2) {
            // os << exp(canonEv(value.toLong()) * log(2.0)) * 100.0 / 32.0;
            ushort16 iso_index = shot_info->getShort(2);
            iso = expf(canonEv((long)iso_index) * logf(2.0)) * 100.0f / 32.0f;
        }
    }

    // Fetch the white balance
    try {
        if(mRootIFD->hasEntryRecursive((CiffTag)0x0032)) {
            CiffEntry *wb = mRootIFD->getEntryRecursive((CiffTag)0x0032);
            if (wb->type == CIFF_BYTE && wb->count == 768) {
                // We're in a D30 file, values are RGGB
                // This will probably not get used anyway as a 0x102c tag should exist
                mRaw->metadata.wbCoeffs[0] = (float) (1024.0 /wb->getByte(72));
                mRaw->metadata.wbCoeffs[1] = (float) ((1024.0/wb->getByte(73))+(1024.0/wb->getByte(74)))/2.0f;
                mRaw->metadata.wbCoeffs[2] = (float) (1024.0 /wb->getByte(75));
            } else if (wb->type == CIFF_BYTE && wb->count > 768) { // Other G series and S series cameras
                // correct offset for most cameras
                int offset = 120;
                // check for the hint that we need to use other offset
                if (hints.find("wb_offset") != hints.end()) {
                    stringstream wb_offset(hints.find("wb_offset")->second);
                    wb_offset >> offset;
                }

                ushort16 key[] = { 0x410, 0x45f3 };
                if (hints.find("wb_mangle") == hints.end())
                    key[0] = key[1] = 0;

                offset /= 2;
                mRaw->metadata.wbCoeffs[0] = (float) (wb->getShort(offset+1) ^ key[1]);
                mRaw->metadata.wbCoeffs[1] = (float) (wb->getShort(offset+0) ^ key[0]);
                mRaw->metadata.wbCoeffs[2] = (float) (wb->getShort(offset+2) ^ key[0]);
            }
Beispiel #17
0
void KdcDecoder::decodeMetaDataInternal(CameraMetaData *meta) {
  vector<TiffIFD*> data = mRootIFD->getIFDsWithTag(MODEL);

  if (data.empty())
    ThrowRDE("KDC Decoder: Model name found");
  if (!data[0]->hasEntry(MAKE))
    ThrowRDE("KDC Decoder: Make name not found");

  string make = data[0]->getEntry(MAKE)->getString();
  string model = data[0]->getEntry(MODEL)->getString();
  setMetaData(meta, make, model, "", 0);

  // Try the kodak hidden IFD for WB
  if (mRootIFD->hasEntryRecursive(KODAK_IFD2)) {
    TiffEntry *ifdoffset = mRootIFD->getEntryRecursive(KODAK_IFD2);
    TiffIFD *kodakifd = NULL;
    try {
      if (mRootIFD->endian == getHostEndianness())
        kodakifd = new TiffIFD(mFile, ifdoffset->getInt());
      else
        kodakifd = new TiffIFDBE(mFile, ifdoffset->getInt());

     if (kodakifd && kodakifd->hasEntryRecursive(KODAK_KDC_WB)) {
        TiffEntry *wb = kodakifd->getEntryRecursive(KODAK_KDC_WB);
        if (wb->count == 3) {
          const uint32 *tmp = wb->getIntArray();
          mRaw->metadata.wbCoeffs[0] = (float)tmp[0];
          mRaw->metadata.wbCoeffs[1] = (float)tmp[1];
          mRaw->metadata.wbCoeffs[2] = (float)tmp[2];
        }
      }
    } catch(TiffParserException e) {
      mRaw->setError(e.what());
    }
    if (kodakifd)
      delete kodakifd;
  }

  // Use the normal WB if available
  if (mRootIFD->hasEntryRecursive(KODAKWB)) {
    TiffEntry *wb = mRootIFD->getEntryRecursive(KODAKWB);
    if (wb->count == 734 || wb->count == 1502) {
      const uchar8 *tmp = wb->getData();
      mRaw->metadata.wbCoeffs[0] = (float)((((ushort16) tmp[148])<<8)|tmp[149])/256.0f;
      mRaw->metadata.wbCoeffs[1] = 1.0f;
      mRaw->metadata.wbCoeffs[2] = (float)((((ushort16) tmp[150])<<8)|tmp[151])/256.0f;
    }
  }
}
Beispiel #18
0
void SrwDecoder::decodeMetaDataInternal(CameraMetaData *meta) {
  mRaw->cfa.setCFA(CFA_RED, CFA_GREEN, CFA_GREEN2, CFA_BLUE);
  vector<TiffIFD*> data = mRootIFD->getIFDsWithTag(MODEL);

  if (data.empty())
    ThrowRDE("SRW Meta Decoder: Model name found");

  string make = data[0]->getEntry(MAKE)->getString();
  string model = data[0]->getEntry(MODEL)->getString();

  data = mRootIFD->getIFDsWithTag(CFAPATTERN);
  if (!this->checkCameraSupported(meta, make, model, "") && !data.empty() && data[0]->hasEntry(CFAREPEATPATTERNDIM)) {
    const unsigned short* pDim = data[0]->getEntry(CFAREPEATPATTERNDIM)->getShortArray();
    iPoint2D cfaSize(pDim[1], pDim[0]);
    if (cfaSize.x != 2 && cfaSize.y != 2)
      ThrowRDE("SRW Decoder: Unsupported CFA pattern size");

    const uchar8* cPat = data[0]->getEntry(CFAPATTERN)->getData();
    if (cfaSize.area() != data[0]->getEntry(CFAPATTERN)->count)
      ThrowRDE("SRW Decoder: CFA pattern dimension and pattern count does not match: %d.");

    for (int y = 0; y < cfaSize.y; y++) {
      for (int x = 0; x < cfaSize.x; x++) {
        uint32 c1 = cPat[x+y*cfaSize.x];
        CFAColor c2;
        switch (c1) {
            case 0:
              c2 = CFA_RED; break;
            case 1:
              c2 = CFA_GREEN; break;
            case 2:
              c2 = CFA_BLUE; break;
            default:
              c2 = CFA_UNKNOWN;
              ThrowRDE("SRW Decoder: Unsupported CFA Color.");
        }
        mRaw->cfa.setColorAt(iPoint2D(x, y), c2);
      }
    }
    printf("Camera CFA: %s\n", mRaw->cfa.asString().c_str());
  }

  int iso = 0;
  if (mRootIFD->hasEntryRecursive(ISOSPEEDRATINGS))
    iso = mRootIFD->getEntryRecursive(ISOSPEEDRATINGS)->getInt();

  setMetaData(meta, make, model, "", iso);
}
Beispiel #19
0
// Interpolate and convert sRaw data.
void Cr2Decoder::sRawInterpolate() {
  vector<TiffIFD*> data = mRootIFD->getIFDsWithTag((TiffTag)0x4001);
  if (data.empty())
    ThrowRDE("CR2 sRaw: Unable to locate WB info.");

  const ushort16 *wb_data = data[0]->getEntry((TiffTag)0x4001)->getShortArray();

  // Offset to sRaw coefficients used to reconstruct uncorrected RGB data.
  wb_data = &wb_data[4+(126+22)/2];

  sraw_coeffs[0] = wb_data[0];
  sraw_coeffs[1] = (wb_data[1] + wb_data[2] + 1) >> 1;
  sraw_coeffs[2] = wb_data[3];

  /* Determine sRaw coefficients */
  bool isOldSraw = hints.find("sraw_40d") != hints.end();
  bool isNewSraw = hints.find("sraw_new") != hints.end();

  if (mRaw->subsampling.y == 1 && mRaw->subsampling.x == 2) {
    if (isOldSraw)
      interpolate_422_old(mRaw->dim.x / 2, mRaw->dim.y , 0, mRaw->dim.y);
    else if (isNewSraw)
      interpolate_422_new(mRaw->dim.x / 2, mRaw->dim.y , 0, mRaw->dim.y);
    else
      interpolate_422(mRaw->dim.x / 2, mRaw->dim.y , 0, mRaw->dim.y);
  } else {
    if (isNewSraw)
      interpolate_420_new(mRaw->dim.x / 2, mRaw->dim.y / 2 , 0 , mRaw->dim.y / 2);
    else
      interpolate_420(mRaw->dim.x / 2, mRaw->dim.y / 2 , 0 , mRaw->dim.y / 2);
  }
}
Beispiel #20
0
void NefDecoder::DecodeD100Uncompressed() {

  ThrowRDE("NEF DEcoder: D100 uncompressed not supported");
  /*
    TiffIFD* raw = mRootIFD->getIFDsWithTag(CFAPATTERN)[0];

    uint32 nslices = raw->getEntry(STRIPOFFSETS)->count;
    uint32 offset = raw->getEntry(STRIPOFFSETS)->getInt();
    uint32 count = raw->getEntry(STRIPBYTECOUNTS)->getInt();
    if (!mFile->isValid(offset+count))
      ThrowRDE("DecodeD100Uncompressed: Truncated file");

    const uchar8 *in =  mFile->getData(offset);

    uint32 w = raw->getEntry(IMAGEWIDTH)->getInt();
    uint32 h = raw->getEntry(IMAGELENGTH)->getInt();

    mRaw->dim = iPoint2D(w, h);
    mRaw->bpp = 2;
    mRaw->createData();

    uchar8* data = mRaw->getData();
    uint32 outPitch = mRaw->pitch;

    BitPumpMSB bits(mFile->getData(offset),count);
    for (uint32 y = 0; y < h; y++) {
      ushort16* dest = (ushort16*)&data[y*outPitch];
      for(uint32 x =0 ; x < w; x++) {
        uint32 b = bits.getBits(12);
        dest[x] = b;
        if ((x % 10) == 9)
          bits.skipBits(8);
      }
    }*/
}
Beispiel #21
0
__inline void BitPumpJPEG::init() {
  current_buffer = (uchar8*)_aligned_malloc(16, 16);
  if (!current_buffer)
    ThrowRDE("BitPumpJPEG::init(): Unable to allocate memory");
  memset(current_buffer,0,16);
  fill();
}
Beispiel #22
0
RawDecoder* X3fParser::getDecoder()
{
  if (NULL == decoder)
    ThrowRDE("X3fParser: No decoder found!");
  RawDecoder *ret = decoder;
  decoder = NULL;
  return ret;
}
void Cr2Decoder::checkSupport(CameraMetaData *meta) {
  vector<TiffIFD*> data = mRootIFD->getIFDsWithTag(MODEL);
  if (data.empty())
    ThrowRDE("CR2 Support check: Model name found");
  string make = data[0]->getEntry(MAKE)->getString();
  string model = data[0]->getEntry(MODEL)->getString();
  this->checkCameraSupported(meta, make, model, "");
}
Beispiel #24
0
void MrwDecoder::checkSupportInternal(CameraMetaData *meta) {
  if (!tiff_meta->hasEntry(MAKE) || !tiff_meta->hasEntry(MODEL))
    ThrowRDE("MRW: Couldn't find make and model");

  string make = tiff_meta->getEntry(MAKE)->getString();
  string model = tiff_meta->getEntry(MODEL)->getString();
  this->checkCameraSupported(meta, make, model, "");
}
Beispiel #25
0
string MosDecoder::getXMPTag(string xmp, string tag) {
  string::size_type start = xmp.find("<tiff:"+tag+">");
  string::size_type end = xmp.find("</tiff:"+tag+">");
  if (start == string::npos || end == string::npos || end <= start)
    ThrowRDE("MOS Decoder: Couldn't find tag '%s' in the XMP", tag.c_str());
  int startlen = tag.size()+7;
  return xmp.substr(start+startlen, end-start-startlen);
}
RawImage PefDecoder::decodeRawInternal() {
  vector<TiffIFD*> data = mRootIFD->getIFDsWithTag(STRIPOFFSETS);

  if (data.empty())
    ThrowRDE("PEF Decoder: No image data found");

  TiffIFD* raw = data[0];

  int compression = raw->getEntry(COMPRESSION)->getInt();

  if (1 == compression) {
    decodeUncompressed(raw, true);
    return mRaw;
  }

  if (65535 != compression)
    ThrowRDE("PEF Decoder: Unsupported compression");

  TiffEntry *offsets = raw->getEntry(STRIPOFFSETS);
  TiffEntry *counts = raw->getEntry(STRIPBYTECOUNTS);

  if (offsets->count != 1) {
    ThrowRDE("PEF Decoder: Multiple Strips found: %u", offsets->count);
  }
  if (counts->count != offsets->count) {
    ThrowRDE("PEF Decoder: Byte count number does not match strip size: count:%u, strips:%u ", counts->count, offsets->count);
  }
  if (!mFile->isValid(offsets->getInt() + counts->getInt()))
    ThrowRDE("PEF Decoder: Truncated file.");

  uint32 width = raw->getEntry(IMAGEWIDTH)->getInt();
  uint32 height = raw->getEntry(IMAGELENGTH)->getInt();

  mRaw->dim = iPoint2D(width, height);
  mRaw->createData();
  try {
    PentaxDecompressor l(mFile, mRaw);
    l.decodePentax(mRootIFD, offsets->getInt(), counts->getInt());
  } catch (IOException &e) {
    errors.push_back(_strdup(e.what()));
    // Let's ignore it, it may have delivered somewhat useful data.
  }

  return mRaw;
}
Beispiel #27
0
void MrwDecoder::parseHeader() {
  const unsigned char* data = mFile->getData(0);
  
  if (mFile->getSize() < 30)
    ThrowRDE("Not a valid MRW file (size too small)");

  if (!isMRW(mFile))
    ThrowRDE("This isn't actually a MRW file, why are you calling me?");
    
  data_offset = get4BE(data,4)+8;

  if (!mFile->isValid(data_offset))
    ThrowRDE("MRW: Data offset is invalid");

  // Make sure all values have at least been initialized
  raw_width = raw_height = packed = 0;
  wb_coeffs[0] = wb_coeffs[1] = wb_coeffs[2] = wb_coeffs[3] = NAN;

  uint32 currpos = 8;
  while (currpos < data_offset) {
    uint32 tag = get4BE(data,currpos);
    uint32 len = get4BE(data,currpos+4);
    switch(tag) {
    case 0x505244: // PRD
      raw_height = get2BE(data,currpos+16);
      raw_width = get2BE(data,currpos+18);
      packed = (data[currpos+24] == 12);
    case 0x574247: // WBG
      for(uint32 i=0; i<4; i++)
        wb_coeffs[i] = (float)get2BE(data, currpos+12+i*2);
      break;
    case 0x545457: // TTW
      // Base value for offsets needs to be at the beginning of the TIFF block, not the file
      FileMap *f = new FileMap(mFile->getDataWrt(currpos+8), mFile->getSize()-currpos-8);
      if (little == getHostEndianness())
        tiff_meta = new TiffIFDBE(f, 8);
      else
        tiff_meta = new TiffIFD(f, 8);
      delete f;
      break;
    }
    currpos += MAX(len+8,1); // MAX(,1) to make sure we make progress
  }
}
Beispiel #28
0
RawImage PefDecoder::decodeRawInternal() {
  auto raw = mRootIFD->getIFDWithTag(STRIPOFFSETS);

  int compression = raw->getEntry(COMPRESSION)->getU32();

  if (1 == compression || compression == 32773) {
    decodeUncompressed(raw, BitOrder_MSB);
    return mRaw;
  }

  if (65535 != compression)
    ThrowRDE("Unsupported compression");

  TiffEntry *offsets = raw->getEntry(STRIPOFFSETS);
  TiffEntry *counts = raw->getEntry(STRIPBYTECOUNTS);

  if (offsets->count != 1) {
    ThrowRDE("Multiple Strips found: %u", offsets->count);
  }
  if (counts->count != offsets->count) {
    ThrowRDE(
        "Byte count number does not match strip size: count:%u, strips:%u ",
        counts->count, offsets->count);
  }
  if (!mFile->isValid(offsets->getU32(), counts->getU32()))
    ThrowRDE("Truncated file.");

  uint32 width = raw->getEntry(IMAGEWIDTH)->getU32();
  uint32 height = raw->getEntry(IMAGELENGTH)->getU32();

  mRaw->dim = iPoint2D(width, height);
  mRaw->createData();
  try {
    PentaxDecompressor::decompress(
        mRaw, ByteStream(mFile, offsets->getU32(), counts->getU32()),
        getRootIFD());
  } catch (IOException &e) {
    mRaw->setError(e.what());
    // Let's ignore it, it may have delivered somewhat useful data.
  }

  return mRaw;
}
Beispiel #29
0
void X3fPropertyCollection::addProperties( ByteStream *bytes, uint32 offset, uint32 length )
{
  bytes->setAbsoluteOffset(offset);
  string id = getIdAsString(bytes);
  if (id.compare("SECp"))
    ThrowRDE("X3fImage:Unknown Property signature");

  uint32 version = bytes->getUInt();
  if (version < 0x00020000)
    ThrowRDE("X3F Decoder: File version too old (properties)");

  uint32 entries = bytes->getUInt();
  if (!entries)
    return;

  if (0 != bytes->getUInt())
    ThrowRDE("X3F Decoder: Unknown property character encoding");

  // Skip 4 reserved bytes
  bytes->skipBytes(4);

  // Skip size (not used ATM)
  bytes->skipBytes(4);

  if (entries > 1000)
    ThrowRDE("X3F Decoder: Unreasonable number of properties: %u", entries);

  uint32 data_start = bytes->getOffset() + entries*8;
  for (uint32 i = 0; i < entries; i++) {
    uint32 key_pos = bytes->getUInt();
    uint32 value_pos = bytes->getUInt();
    bytes->pushOffset();
    try {
      bytes->setAbsoluteOffset(key_pos * 2 + data_start);
      string key = getString(bytes);
      bytes->setAbsoluteOffset(value_pos * 2 + data_start);
      string val = getString(bytes);
      props[key] = val;
    } catch (IOException) {}
    bytes->popOffset();
  }
}
Beispiel #30
0
void X3fDecoder::checkSupportInternal( CameraMetaData *meta )
{
  if (readName()) {
    if (!checkCameraSupported(meta, camera_make, camera_model, "" ))
      ThrowRDE("X3FDecoder: Unknown camera. Will not guess.");
    return;
  }

  // If we somehow got to here without a camera, see if we have an image
  // with proper format identifiers.
  vector<X3fImage>::iterator img = mImages.begin();
  for (; img !=  mImages.end(); img++) {
    X3fImage cimg = *img;
    if (cimg.type == 1 || cimg.type == 3) {
      if (cimg.format == 30 || cimg.format == 35)
        return;
    }
  }
  ThrowRDE("X3F Decoder: Unable to determine camera name.");
}