Author: post
Date: 2011-04-19 14:11:34 +0200 (Tue, 19 Apr 2011)
New Revision: 364
Modified:
RawSpeed/NefDecoder.cpp
RawSpeed/NefDecoder.h
Log:
Add Special decoder for very old Nikon Coolpix.
Modified: RawSpeed/NefDecoder.cpp
===================================================================
--- RawSpeed/NefDecoder.cpp 2011-04-13 22:42:21 UTC (rev 363)
+++ RawSpeed/NefDecoder.cpp 2011-04-19 12:11:34 UTC (rev 364)
@@ -28,7 +28,7 @@
NefDecoder::NefDecoder(TiffIFD *rootIFD, FileMap* file) :
RawDecoder(file), mRootIFD(rootIFD) {
- decoderVersion = 2;
+ decoderVersion = 3;
}
NefDecoder::~NefDecoder(void) {
@@ -143,9 +143,23 @@
return false;
}
+TiffIFD* NefDecoder::FindBestImage(vector<TiffIFD*>* data) {
+ int largest_width = 0;
+ TiffIFD* best_ifd = NULL;
+ for (int i = 0; i < (int)data->size(); i++) {
+ TiffIFD* raw = (*data)[i];
+ int width = raw->getEntry(IMAGEWIDTH)->getInt();
+ if (width > largest_width)
+ best_ifd = raw;
+ }
+ if (NULL == best_ifd)
+ ThrowRDE("NEF Decoder: Unable to locate image");
+ return best_ifd;
+}
+
void NefDecoder::DecodeUncompressed() {
vector<TiffIFD*> data = mRootIFD->getIFDsWithTag(CFAPATTERN);
- TiffIFD* raw = data[0];
+ TiffIFD* raw = FindBestImage(&data);
uint32 nslices = raw->getEntry(STRIPOFFSETS)->count;
const uint32 *offsets = raw->getEntry(STRIPOFFSETS)->getIntArray();
const uint32 *counts = raw->getEntry(STRIPBYTECOUNTS)->getIntArray();
@@ -187,10 +201,12 @@
iPoint2D size(width, slice.h);
iPoint2D pos(0, offY);
try {
- if (hints.find(string("coolpixmangled")) == hints.end())
+ if (hints.find(string("coolpixmangled")) != hints.end())
+ readCoolpixMangledRaw(in, size, pos, width*bitPerPixel / 8);
+ else if (hints.find(string("coolpixsplit")) != hints.end())
+ readCoolpixSplitRaw(in, size, pos, width*bitPerPixel / 8);
+ else
readUncompressedRaw(in, size, pos, width*bitPerPixel / 8, bitPerPixel,
true);
- else
- readCoolpixMangledRaw(in, size, pos, width*bitPerPixel / 8);
} catch (RawDecoderException e) {
if (i>0)
errors.push_back(_strdup(e.what()));
@@ -236,6 +252,44 @@
}
}
+
+void NefDecoder::readCoolpixSplitRaw(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("readCoolpixSplitRaw: Invalid y offset");
+ if (offset.x + size.x > mRaw->dim.x)
+ ThrowRDE("readCoolpixSplitRaw: Invalid x offset");
+
+ uint32 y = offset.y;
+ h = MIN(h + (uint32)offset.y, (uint32)mRaw->dim.y);
+ w *= cpp;
+ h /= 2;
+ BitPumpMSB *in = new BitPumpMSB(&input);
+ for (; y < h; y++) {
+ ushort16* dest = (ushort16*) &
data[offset.x*sizeof(ushort16)*cpp+y*2*outPitch];
+ for (uint32 x = 0 ; x < w; x++) {
+ dest[x] = in->getBits(12);
+ }
+ }
+ for (y = offset.y; y < h; y++) {
+ ushort16* dest = (ushort16*) &
data[offset.x*sizeof(ushort16)*cpp+(y*2+1)*outPitch];
+ for (uint32 x = 0 ; x < w; x++) {
+ dest[x] = in->getBits(12);
+ }
+ }
+}
+
void NefDecoder::DecodeD100Uncompressed() {
ThrowRDE("NEF DEcoder: D100 uncompressed not supported");
Modified: RawSpeed/NefDecoder.h
===================================================================
--- RawSpeed/NefDecoder.h 2011-04-13 22:42:21 UTC (rev 363)
+++ RawSpeed/NefDecoder.h 2011-04-19 12:11:34 UTC (rev 364)
@@ -46,6 +46,8 @@
void DecodeUncompressed();
void DecodeD100Uncompressed();
void readCoolpixMangledRaw(ByteStream &input, iPoint2D& size, iPoint2D&
offset, int inputPitch);
+ void readCoolpixSplitRaw(ByteStream &input, iPoint2D& size, iPoint2D&
offset, int inputPitch);
+ TiffIFD* FindBestImage(vector<TiffIFD*>* data);
};
class NefSlice {
_______________________________________________
Rawstudio-commit mailing list
[email protected]
http://rawstudio.org/cgi-bin/mailman/listinfo/rawstudio-commit