BaseJpegDeocde exampe program

Dependencies:   BaseJpegDecode Terminal BaseUsbHost mbed mbed-rtos

Fork of BaseJpegDecode by Norimasa Okamoto

Revision:
5:033432f9baf3
Parent:
4:7d88de31c55a
--- a/SimpleJpegDecode.cpp	Tue Oct 30 15:35:36 2012 +0000
+++ b/SimpleJpegDecode.cpp	Thu Nov 15 10:20:38 2012 +0000
@@ -3,18 +3,42 @@
 #define DBG(...) do{fprintf(stderr,"[%s@%d] ",__PRETTY_FUNCTION__,__LINE__);fprintf(stderr,__VA_ARGS__);} while(0);
 #define ASSERT(A) while(!(A)){fprintf(stderr,"\n\n%s@%d %s ASSERT!\n\n",__PRETTY_FUNCTION__,__LINE__,#A);exit(1);};
 
-SimpleJpegDecode::SimpleJpegDecode()
+
+#define _1_4020 45
+#define _0_3441 11
+#define _0_7139 23
+#define _1_7718 57
+#define _0_0012 0
+
+int adjust(int r) {
+    if (r >= 0) {
+        if (r <= 255) {
+            return r;
+        } else {
+            return 255;
+        }
+    } else {
+        return 0;
+    }
+}
+    
+void convYUVtoRGB(uint8_t rgb[], int y, int u, int v)
 {
-    for(int i = 0; i < 6; i++) {
-        m_block_data[i] = new uint8_t[64];
-        ASSERT(m_block_data[i]);
-    }
+    rgb[0] = adjust((y*32             + v*_1_4020)/32 + 128);
+    rgb[1] = adjust((y*32 - u*_0_3441 - v*_0_7139)/32 + 128);
+    rgb[2] = adjust((y*32 + u*_1_7718 - v*_0_0012)/32 + 128);
+}
+
+SimpleJpegDecode::SimpleJpegDecode(uint8_t output_mode)
+{
+    m_output_mode = output_mode;
     clearOnResult();
 }
 
+
 void SimpleJpegDecode::output(int mcu, int block, int scan, int value)
 {
-    int sc = (block < m_yblocks) ? 0 : 1;
+    int sc = (block < yblock) ? 0 : 1;
     inputBLOCK(mcu, block, scan, value * qt[sc][scan]);
 }
 
@@ -34,38 +58,83 @@
 {
 }
 
-void SimpleJpegDecode::outputBLOCK(int mcu, int block, uint8_t* values)
+void SimpleJpegDecode::format_YUV(int mcu, int block, int8_t* values)
 {
-    BLOCK_count++;
-
-    memcpy(m_block_data[block], values, 64);
-    if (block < m_yblocks+1) {
+    if (block < yblock+1) {
+        memcpy(m_block_data[block], values, 64);
         return;
     }
-    int mcu_x = mcu % (width/16);
-    int mcu_y = mcu / (width/16);
+    int mcu_x_count = (width+15)/16;
+    int mcu_x = mcu % mcu_x_count;
+    int mcu_y = mcu / mcu_x_count;
     uint8_t yuv[3];
-    if (m_yblocks == 2) {
+    if (yblock == 2) {
         for(int y = 0; y < 8; y++) {
             for(int x = 0; x < 16; x++) {
-                yuv[0] = m_block_data[x/8][y*8+x%8];
-                yuv[1] = m_block_data[2][y*8+x/2];
-                yuv[2] = m_block_data[3][y*8+x/2];
+                yuv[0] = m_block_data[x/8][y*8+x%8] + 128;
+                yuv[1] = m_block_data[2][y*8+x/2] + 128;
+                yuv[2] = values[y*8+x/2] + 128;
                 onResult(mcu_x * 16 + x, mcu_y * 8 + y, yuv);
             }
         }
-    } else if (m_yblocks == 4) {
+    } else if (yblock == 4) {
         for(int y = 0; y < 16; y++) {
             for(int x = 0; x < 16; x++) {
-                int block = (y/8)*2+x/8;
-                yuv[0] = m_block_data[block][(y%8)*8+x%8];
-                yuv[1] = m_block_data[4][(y/2)*8+x/2];
-                yuv[2] = m_block_data[5][(y/2)*8+x/2];
+                yuv[0] = m_block_data[(y/8)*2+x/8][(y%8)*8+x%8] + 128;
+                yuv[1] = m_block_data[4][(y/2)*8+x/2] + 128;
+                yuv[2] = values[(y/2)*8+x/2] + 128;
                 onResult(mcu_x * 16 + x, mcu_y * 16 + y, yuv);
             }
         }
     } else {
-        ASSERT(m_yblocks == 2 || m_yblocks == 4);
+        ASSERT(yblock == 2 || yblock == 4);
+    }    
+}
+
+void SimpleJpegDecode::format_RGB24(int mcu, int block, int8_t* values)
+{
+    if (block < yblock+1) {
+        memcpy(m_block_data[block], values, 64);
+        return;
+    }
+    int mcu_x_count = (width+15)/16;
+    int mcu_x = mcu % mcu_x_count;
+    int mcu_y = mcu / mcu_x_count;
+    uint8_t rgb[3];
+    if (yblock == 2) {
+        for(int y = 0; y < 8; y++) {
+            for(int x = 0; x < 16; x++) {
+                int8_t yuv_y = m_block_data[x/8][y*8+x%8];
+                int8_t yuv_u = m_block_data[2][y*8+x/2];
+                int8_t yuv_v = values[y*8+x/2];
+                convYUVtoRGB(rgb, yuv_y, yuv_u, yuv_v);
+                onResult(mcu_x * 16 + x, mcu_y * 8 + y, rgb);
+            }
+        }
+    } else if (yblock == 4) {
+        for(int y = 0; y < 16; y++) {
+            for(int x = 0; x < 16; x++) {
+                int8_t yuv_y = m_block_data[(y/8)*2+x/8][(y%8)*8+x%8];
+                int8_t yuv_u = m_block_data[4][(y/2)*8+x/2];
+                int8_t yuv_v = values[(y/2)*8+x/2];
+                convYUVtoRGB(rgb, yuv_y, yuv_u, yuv_v);
+                onResult(mcu_x * 16 + x, mcu_y * 16 + y, rgb);
+            }
+        }
+    } else {
+        ASSERT(yblock == 2 || yblock == 4);
+    }    
+}
+
+void SimpleJpegDecode::outputBLOCK(int mcu, int block, int8_t* values)
+{
+    BLOCK_count++;
+    if (m_output_mode == YUV) {
+        format_YUV(mcu, block, values);
+    } else if (m_output_mode == RGB24) {
+        format_RGB24(mcu, block, values);
+    } else {
+        ASSERT(m_output_mode == YUV || m_output_mode == RGB24);
     }    
 }