Author: post
Date: 2013-06-01 14:53:54 +0200 (Sat, 01 Jun 2013)
New Revision: 548
Modified:
RawSpeed/SrwDecoder.cpp
RawSpeed/SrwDecoder.h
Log:
Add support for compressed Samsung images.
Modified: RawSpeed/SrwDecoder.cpp
===================================================================
--- RawSpeed/SrwDecoder.cpp 2013-06-01 11:38:04 UTC (rev 547)
+++ RawSpeed/SrwDecoder.cpp 2013-06-01 12:53:54 UTC (rev 548)
@@ -1,6 +1,8 @@
#include "StdAfx.h"
#include "SrwDecoder.h"
#include "TiffParserOlympus.h"
+#include "ByteStreamSwap.h"
+
#if defined(__unix__) || defined(__APPLE__)
#include <stdlib.h>
#endif
@@ -30,7 +32,7 @@
SrwDecoder::SrwDecoder(TiffIFD *rootIFD, FileMap* file):
RawDecoder(file), mRootIFD(rootIFD) {
- decoderVersion = 2;
+ decoderVersion = 3;
}
SrwDecoder::~SrwDecoder(void) {
@@ -65,17 +67,117 @@
if (32770 == compression)
{
- bool bit_order = (bits == 12); // Default guess
- map<string,string>::iterator msb_hint = hints.find("msb_override");
- if (msb_hint != hints.end())
- bit_order = (0 == (msb_hint->second).compare("true"));
- this->decodeUncompressed(raw, bit_order ? BitOrder_Jpeg : BitOrder_Plain);
- return mRaw;
+ if (!raw->hasEntry ((TiffTag)40976)) {
+ bool bit_order = (bits == 12); // Default guess
+ map<string,string>::iterator msb_hint = hints.find("msb_override");
+ if (msb_hint != hints.end())
+ bit_order = (0 == (msb_hint->second).compare("true"));
+ this->decodeUncompressed(raw, bit_order ? BitOrder_Jpeg :
BitOrder_Plain);
+ return mRaw;
+ } else {
+ uint32 nslices = raw->getEntry(STRIPOFFSETS)->count;
+ if (nslices != 1)
+ ThrowRDE("Srw Decoder: Only one slice supported, found %u", nslices);
+ try {
+ decodeCompressed(raw);
+ } catch (RawDecoderException& e) {
+ mRaw->setError(e.what());
+ }
+ return mRaw;
+ }
}
ThrowRDE("Srw Decoder: Unsupported compression");
return mRaw;
}
+// Decoder for compressed srw files (NX300 and later)
+void SrwDecoder::decodeCompressed( TiffIFD* raw )
+{
+ uint32 width = raw->getEntry(IMAGEWIDTH)->getInt();
+ uint32 height = raw->getEntry(IMAGELENGTH)->getInt();
+ mRaw->dim = iPoint2D(width, height);
+ mRaw->createData();
+ const uint32 offset = raw->getEntry(STRIPOFFSETS)->getInt();
+ const uint32 count = raw->getEntry(STRIPBYTECOUNTS)->getInt();
+ uint32 compressed_offset = raw->getEntry((TiffTag)40976)->getInt();
+ ByteStream *b;
+ if (getHostEndianness() == little)
+ b = new ByteStream(mFile->getData(0), mFile->getSize());
+ else
+ b = new ByteStreamSwap(mFile->getData(0), mFile->getSize());
+ b->setAbsoluteOffset(compressed_offset);
+ for (uint32 y = 0; y < height; y++) {
+ uint32 line_offset = offset + b->getInt();
+ if (line_offset >= mFile->getSize())
+ ThrowRDE("Srw decoder: Offset outside image file, file probably
truncated.");
+ int len[4];
+ for (int i = 0; i < 4; i++)
+ len[i] = y < 2 ? 7 : 4;
+ BitPumpMSB32 bits(mFile->getData(line_offset),mFile->getSize() -
line_offset);
+ int op[4];
+ ushort16* img = (ushort16*)mRaw->getData(0, y);
+ ushort16* img_up = (ushort16*)mRaw->getData(0, max(0, (int)y - 1));
+ ushort16* img_up2 = (ushort16*)mRaw->getData(0, max(0, (int)y - 2));
+ // Image is arranged in groups of 16 pixels horizontally
+ for (uint32 x = 0; x < width; x += 16) {
+ bool dir = !!bits.getBit();
+ for (int i = 0; i < 4; i++)
+ op[i] = bits.getBits(2);
+ for (int i = 0; i < 4; i++) {
+ switch (op[i]) {
+ case 3: len[i] = bits.getBits(4);
+ break;
+ case 2: len[i]--;
+ break;
+ case 1: len[i]++;
+ }
+ if (len[i] < 0)
+ ThrowRDE("Srw Decompressor: Bit length less than 0.");
+ if (len[i] > 16)
+ ThrowRDE("Srw Decompressor: Bit Length more than 16.");
+ }
+ if (dir) {
+ // Upward prediction
+ // First we decode even pixels
+ for (int c = 0; c < 16; c += 2) {
+ int b = len[(c >> 3)];
+ int32 adj = ((int32) bits.getBits(b) << (32-b) >> (32-b));
+ img[c] = adj + img_up[c];
+ }
+ // Now we decode odd pixels
+ // Why on earth upward prediction only looks up 1 line above
+ // is beyond me, it will hurt compression a deal.
+ for (int c = 1; c < 16; c += 2) {
+ int b = len[2 | (c >> 3)];
+ int32 adj = ((int32) bits.getBits(b) << (32-b) >> (32-b));
+ img[c] = adj + img_up2[c];
+ }
+ } else {
+ // Left to right prediction
+ // First we decode even pixels
+ int pred_left = x ? img[-2] : 128;
+ for (int c = 0; c < 16; c += 2) {
+ int b = len[(c >> 3)];
+ int32 adj = ((int32) bits.getBits(b) << (32-b) >> (32-b));
+ img[c] = adj + pred_left;
+ }
+ // Now we decode odd pixels
+ pred_left = x ? img[-1] : 128;
+ for (int c = 1; c < 16; c += 2) {
+ int b = len[2 | (c >> 3)];
+ int32 adj = ((int32) bits.getBits(b) << (32-b) >> (32-b));
+ img[c] = adj + pred_left;
+ }
+ }
+ bits.checkPos();
+ img += 16;
+ img_up += 16;
+ img_up2 += 16;
+ }
+ }
+}
+
+
void SrwDecoder::checkSupportInternal(CameraMetaData *meta) {
vector<TiffIFD*> data = mRootIFD->getIFDsWithTag(MODEL);
if (data.empty())
@@ -126,7 +228,7 @@
mRaw->cfa.setColorAt(iPoint2D(x, y), c2);
}
}
- printf("Camera CFA: %s\n", mRaw->cfa.asString().c_str());
+ //printf("Camera CFA: %s\n", mRaw->cfa.asString().c_str());
}
int iso = 0;
@@ -136,4 +238,5 @@
setMetaData(meta, make, model, "", iso);
}
+
} // namespace RawSpeed
Modified: RawSpeed/SrwDecoder.h
===================================================================
--- RawSpeed/SrwDecoder.h 2013-06-01 11:38:04 UTC (rev 547)
+++ RawSpeed/SrwDecoder.h 2013-06-01 12:53:54 UTC (rev 548)
@@ -40,6 +40,7 @@
virtual void decodeMetaDataInternal(CameraMetaData *meta);
virtual void checkSupportInternal(CameraMetaData *meta);
private:
+ void SrwDecoder::decodeCompressed( TiffIFD* raw);
TiffIFD *mRootIFD;
};
_______________________________________________
Rawstudio-commit mailing list
[email protected]
http://rawstudio.org/cgi-bin/mailman/listinfo/rawstudio-commit