[Rawstudio-commit] rawspeed r59 - RawSpeed

Klaus Post klauspost at gmail.com
Sun Feb 8 16:01:33 CET 2009


Author: post
Date: 2009-02-08 16:01:33 +0100 (Sun, 08 Feb 2009)
New Revision: 59

Modified:
   RawSpeed/BitPumpJPEG.cpp
   RawSpeed/BitPumpJPEG.h
   RawSpeed/ByteStream.cpp
   RawSpeed/DngDecoder.cpp
   RawSpeed/LJpegDecompressor.cpp
   RawSpeed/Point.h
   RawSpeed/RawImage.cpp
   RawSpeed/RawImage.h
Log:
- Added DNG Cropping.
- Subframe feature in RawImage.
- Commented out debugging info in LJPEG Decoder.
- Cosmetic: Skip stuffed bytes in Lossless Jpeg.

Modified: RawSpeed/BitPumpJPEG.cpp
===================================================================
--- RawSpeed/BitPumpJPEG.cpp	2009-02-08 12:31:19 UTC (rev 58)
+++ RawSpeed/BitPumpJPEG.cpp	2009-02-08 15:01:33 UTC (rev 59)
@@ -45,6 +45,7 @@
    for (int i = 0; i < 31; i++) {
      masks[i] = (1<<i)-1;
    }
+   stuffed = 0;
    fill();
  }
 
@@ -65,6 +66,7 @@
         }  else {
           c = 0;
           off--;  // Don't return more bytes, rewind, so this will be hit next          
+          stuffed++;
         }
       }
       /*

Modified: RawSpeed/BitPumpJPEG.h
===================================================================
--- RawSpeed/BitPumpJPEG.h	2009-02-08 12:31:19 UTC (rev 58)
+++ RawSpeed/BitPumpJPEG.h	2009-02-08 15:01:33 UTC (rev 59)
@@ -42,7 +42,7 @@
 	guchar getByte();
 	guchar getByteSafe();
 	void setAbsoluteOffset(guint offset);     // Set offset in bytes
-  guint getOffset() { return off-(mLeft>>3);}
+  guint getOffset() { return off-(mLeft>>3)+stuffed;}
   __inline guint getBitNoFill() {return (mCurr >> (--mLeft)) & 1;}
   __inline guint peekByteNoFill() {return ((mCurr >> (mLeft-8))) & 0xff; }
   __inline guint peekBitsNoFill(guint nbits) {return ((mCurr >> (mLeft-nbits))) &masks[nbits]; }
@@ -59,6 +59,7 @@
   guint mLeft;
   guint mCurr;
   guint off;                  // Offset in bytes
+  guint stuffed;              // How many bytes has been stuffed?
 private:
 };
 

Modified: RawSpeed/ByteStream.cpp
===================================================================
--- RawSpeed/ByteStream.cpp	2009-02-08 12:31:19 UTC (rev 58)
+++ RawSpeed/ByteStream.cpp	2009-02-08 15:01:33 UTC (rev 59)
@@ -85,5 +85,5 @@
     if (off>=size)
       throw IOException("No marker found inside rest of buffer");
   }
-  _RPT1(0,"Skipped %u bytes.\n", c);
+//  _RPT1(0,"Skipped %u bytes.\n", c);
 }

Modified: RawSpeed/DngDecoder.cpp
===================================================================
--- RawSpeed/DngDecoder.cpp	2009-02-08 12:31:19 UTC (rev 58)
+++ RawSpeed/DngDecoder.cpp	2009-02-08 15:01:33 UTC (rev 59)
@@ -95,8 +95,17 @@
 
       const unsigned short* pDim = raw->getEntry(CFAREPEATPATTERNDIM)->getShortArray(); // Get the size
       const unsigned char* cPat = raw->getEntry(CFAPATTERN)->getData();                 // Does NOT contain dimensions as some documents state
-//      const unsigned char* cPlaneOrder = raw->getEntry(CFAPLANECOLOR)->getData();       // Map from the order in the image, to the position in the CFA
 
+      if (raw->hasEntry(CFAPLANECOLOR)) {
+        TiffEntry* e = raw->getEntry(CFAPLANECOLOR);
+        const unsigned char* cPlaneOrder = e->getData();       // Map from the order in the image, to the position in the CFA
+        printf("Planecolor: ");
+        for (guint i = 0; i < e->count; i++) {
+          printf("%u,",cPlaneOrder[i]);
+        }
+        printf("\n");        
+      }
+
       iPoint2D cfaSize(pDim[1],pDim[0]);
       if (pDim[0] != 2)
         ThrowRDE("DNG Decoder: Unsupported CFA configuration.");
@@ -105,7 +114,7 @@
       
       if (cfaSize.area() != raw->getEntry(CFAPATTERN)->count)
         ThrowRDE("DNG 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++) {
           guint c1 = cPat[x+y*cfaSize.x];
@@ -234,6 +243,13 @@
     ThrowRDE("DNG Decoder: Image could not be read.");
   }
 
+  // Crop
+  if (raw->hasEntry(ACTIVEAREA)) {
+    const guint *corners = raw->getEntry(ACTIVEAREA)->getIntArray();
+    iPoint2D top_left(corners[1], corners[0]);
+    iPoint2D new_size(corners[3]-corners[1], corners[2]-corners[0]);
+    mRaw->subFrame(top_left,new_size);
+  }
   // Linearization
 
   if (raw->hasEntry(LINEARIZATIONTABLE)) {

Modified: RawSpeed/LJpegDecompressor.cpp
===================================================================
--- RawSpeed/LJpegDecompressor.cpp	2009-02-08 12:31:19 UTC (rev 58)
+++ RawSpeed/LJpegDecompressor.cpp	2009-02-08 15:01:33 UTC (rev 59)
@@ -106,7 +106,7 @@
 
     if (getNextMarker(false) != M_SOI)
       ThrowRDE("LJpegDecompressor::startDecoder: Image did not start with SOI. Probably not an LJPEG");
-    _RPT0(0,"Found SOI marker\n");
+//    _RPT0(0,"Found SOI marker\n");
 
     gboolean moreImage = true;
     while (moreImage) {
@@ -114,16 +114,16 @@
 
         switch (m) {
         case M_SOS:
-          _RPT0(0,"Found SOS marker\n");
+//          _RPT0(0,"Found SOS marker\n");
           parseSOS();
             break;
         case M_EOI:
-          _RPT0(0,"Found EOI marker\n");
+//          _RPT0(0,"Found EOI marker\n");
           moreImage = false;
           break;
 
         case M_DHT:
-          _RPT0(0,"Found DHT marker\n");
+//          _RPT0(0,"Found DHT marker\n");
             parseDHT();
             break;
 
@@ -132,15 +132,15 @@
             break;
 
         case M_DRI:
-          _RPT0(0,"Found DRI marker\n");
+//          _RPT0(0,"Found DRI marker\n");
             break;
 
         case M_APP0:
-          _RPT0(0,"Found APP0 marker\n");
+//          _RPT0(0,"Found APP0 marker\n");
             break;
 
         case M_SOF3:
-          _RPT0(0,"Found SOF 3 marker:\n");
+//          _RPT0(0,"Found SOF 3 marker:\n");
           parseSOF(&frame);
           break;
 
@@ -212,18 +212,18 @@
       ThrowRDE("LJpegDecompressor::parseSOS: Invalid Huffman table selection, not defined.");
 
     frame.compInfo[count].dcTblNo = td;
-    _RPT2(0,"Component Selector:%u, Table Dest:%u\n",cs, td);
+//    _RPT2(0,"Component Selector:%u, Table Dest:%u\n",cs, td);
   }
 
   pred = input->getByte();
-  _RPT1(0,"Predictor:%u, ",pred);
+//  _RPT1(0,"Predictor:%u, ",pred);
   if (pred>7)
     ThrowRDE("LJpegDecompressor::parseSOS: Invalid predictor mode.");
 
   input->skipBytes(1);                    // Se + Ah Not used in LJPEG
   guint b = input->getByte();
   Pt = b&0xf;          // Point Transform
-  _RPT1(0,"Point transform:%u\n",Pt);
+//  _RPT1(0,"Point transform:%u\n",Pt);
 
   guint cheadersize = 3+frame.cps * 2 + 3;
   _ASSERTE(cheadersize == headerLength);
@@ -252,7 +252,7 @@
 	  guint Th = b&0xf;
 	  if (Th>3)
 	    ThrowRDE("LJpegDecompressor::parseDHT: Invalid huffman table destination id.");
-    _RPT1(0, "Decoding Table:%u\n",Th);
+//    _RPT1(0, "Decoding Table:%u\n",Th);
 
 	  guint acc = 0;
 	  HuffmanTable* t = &huff[Th];

Modified: RawSpeed/Point.h
===================================================================
--- RawSpeed/Point.h	2009-02-08 12:31:19 UTC (rev 58)
+++ RawSpeed/Point.h	2009-02-08 15:01:33 UTC (rev 59)
@@ -30,8 +30,15 @@
 public:
 	iPoint2D() {x = y = 0;  }
 	iPoint2D( int a, int b) {x=a; y=b;}
+  iPoint2D( iPoint2D& pt) {x=pt.x; y=pt.y;}
+  iPoint2D operator+= (const iPoint2D other) { x += other.x; y += other.y; return *this;}
+  iPoint2D operator-= (const iPoint2D other) { x -= other.x; y -= other.y; return *this;}
+  iPoint2D operator- (const iPoint2D b) { return iPoint2D(x-b.x,y-b.y); }
+  iPoint2D operator+ (const iPoint2D b) { return iPoint2D(x+b.x,y+b.y); }
+  iPoint2D iPoint2D::operator=(iPoint2D b) { x = b.x; y = b.y; return *this;}
 	~iPoint2D() {};
   guint area() {return abs(x*y);}
+  gboolean isThisInside(iPoint2D &otherPoint) {return (x<otherPoint.x && y<otherPoint.y); };
   int x,y;
 };
 

Modified: RawSpeed/RawImage.cpp
===================================================================
--- RawSpeed/RawImage.cpp	2009-02-08 12:31:19 UTC (rev 58)
+++ RawSpeed/RawImage.cpp	2009-02-08 15:01:33 UTC (rev 59)
@@ -65,20 +65,33 @@
 {
   if (!data)
     ThrowRDE("RawImageData::getData - Data not yet allocated.");
-  return data;
+  return &data[mOffset.y*pitch+mOffset.x*bpp];
 }
 
 guchar* RawImageData::getData( guint x, guint y )
 {
+  x+= mOffset.x;
+  y+= mOffset.y;
+
   if (!data)
     ThrowRDE("RawImageData::getData - Data not yet allocated.");
   if (x>=dim.x)
     ThrowRDE("RawImageData::getData - X Position outside image requested.");
   if (y>=dim.y)
     ThrowRDE("RawImageData::getData - Y Position outside image requested.");
+
   return &data[y*pitch+x*bpp];
 }
 
+void RawImageData::subFrame( iPoint2D offset, iPoint2D new_size )
+{
+  if (!new_size.isThisInside(dim+offset+mOffset))
+    ThrowRDE("RawImageData::subFrame - Attempted to create new subframe larger than original size.");
+
+  mOffset += offset;
+  dim = new_size;
+}
+
 RawImage::RawImage( RawImageData* p ) : p_(p)
 {
   pthread_mutex_lock(&p_->mymutex);

Modified: RawSpeed/RawImage.h
===================================================================
--- RawSpeed/RawImage.h	2009-02-08 12:31:19 UTC (rev 58)
+++ RawSpeed/RawImage.h	2009-02-08 15:01:33 UTC (rev 59)
@@ -39,6 +39,7 @@
   guchar* getData(guint x, guint y);    // Not super fast, but safe. Don't use per pixel.
   gboolean isCFA;
   ColorFilterArray cfa;
+  void subFrame( iPoint2D offset, iPoint2D new_size );
 private:
   RawImageData(void);
   RawImageData(iPoint2D dim, guint bpp, guint cpp=1);
@@ -47,6 +48,7 @@
   guint cpp;      // Components per pixel
   friend class RawImage;
   pthread_mutex_t mymutex;
+  iPoint2D mOffset;
 };
 
 




More information about the Rawstudio-commit mailing list