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); } } }
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); } } }
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); } }
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; }
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; }
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; }
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); }
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 {
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, ""); }
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; }
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, ""); }
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); }
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]); }
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; } } }
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); }
// 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); } }
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); } }*/ }
__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(); }
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, ""); }
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, ""); }
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; }
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 } }
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; }
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(); } }
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."); }