test

Dependencies:   Nanopb iSerial mbed BaseJpegDecode FatFileSystem SDFileSystem RingBuffer Camera_LS_Y201

Committer:
cgraham
Date:
Thu Sep 18 15:21:47 2014 +0000
Revision:
0:d69efd0ee139
test

Who changed what in which revision?

UserRevisionLine numberNew contents of line
cgraham 0:d69efd0ee139 1 #include "SimpleJpegDecode.h"
cgraham 0:d69efd0ee139 2
cgraham 0:d69efd0ee139 3 #define DBG(...) do{fprintf(stderr,"[%s@%d] ",__PRETTY_FUNCTION__,__LINE__);fprintf(stderr,__VA_ARGS__);} while(0);
cgraham 0:d69efd0ee139 4 #define ASSERT(A) while(!(A)){fprintf(stderr,"\n\n%s@%d %s ASSERT!\n\n",__PRETTY_FUNCTION__,__LINE__,#A);exit(1);};
cgraham 0:d69efd0ee139 5
cgraham 0:d69efd0ee139 6
cgraham 0:d69efd0ee139 7 #define _1_4020 45
cgraham 0:d69efd0ee139 8 #define _0_3441 11
cgraham 0:d69efd0ee139 9 #define _0_7139 23
cgraham 0:d69efd0ee139 10 #define _1_7718 57
cgraham 0:d69efd0ee139 11 #define _0_0012 0
cgraham 0:d69efd0ee139 12
cgraham 0:d69efd0ee139 13 int adjust(int r) {
cgraham 0:d69efd0ee139 14 if (r >= 0) {
cgraham 0:d69efd0ee139 15 if (r <= 255) {
cgraham 0:d69efd0ee139 16 return r;
cgraham 0:d69efd0ee139 17 } else {
cgraham 0:d69efd0ee139 18 return 255;
cgraham 0:d69efd0ee139 19 }
cgraham 0:d69efd0ee139 20 } else {
cgraham 0:d69efd0ee139 21 return 0;
cgraham 0:d69efd0ee139 22 }
cgraham 0:d69efd0ee139 23 }
cgraham 0:d69efd0ee139 24
cgraham 0:d69efd0ee139 25 void convYUVtoRGB(uint8_t rgb[], int y, int u, int v)
cgraham 0:d69efd0ee139 26 {
cgraham 0:d69efd0ee139 27 rgb[0] = adjust((y*32 + v*_1_4020)/32 + 128);
cgraham 0:d69efd0ee139 28 rgb[1] = adjust((y*32 - u*_0_3441 - v*_0_7139)/32 + 128);
cgraham 0:d69efd0ee139 29 rgb[2] = adjust((y*32 + u*_1_7718 - v*_0_0012)/32 + 128);
cgraham 0:d69efd0ee139 30 }
cgraham 0:d69efd0ee139 31
cgraham 0:d69efd0ee139 32 SimpleJpegDecode::SimpleJpegDecode(uint8_t output_mode)
cgraham 0:d69efd0ee139 33 {
cgraham 0:d69efd0ee139 34 m_output_mode = output_mode;
cgraham 0:d69efd0ee139 35 clearOnResult();
cgraham 0:d69efd0ee139 36 }
cgraham 0:d69efd0ee139 37
cgraham 0:d69efd0ee139 38
cgraham 0:d69efd0ee139 39 void SimpleJpegDecode::output(int mcu, int block, int scan, int value)
cgraham 0:d69efd0ee139 40 {
cgraham 0:d69efd0ee139 41 int sc = (block < yblock) ? 0 : 1;
cgraham 0:d69efd0ee139 42 inputBLOCK(mcu, block, scan, value * qt[sc][scan]);
cgraham 0:d69efd0ee139 43 }
cgraham 0:d69efd0ee139 44
cgraham 0:d69efd0ee139 45 void SimpleJpegDecode::outputDC(int mcu, int block, int value)
cgraham 0:d69efd0ee139 46 {
cgraham 0:d69efd0ee139 47 output(mcu, block, 0, value);
cgraham 0:d69efd0ee139 48 DC_count++;
cgraham 0:d69efd0ee139 49 }
cgraham 0:d69efd0ee139 50
cgraham 0:d69efd0ee139 51 void SimpleJpegDecode::outputAC(int mcu, int block, int scan, int value)
cgraham 0:d69efd0ee139 52 {
cgraham 0:d69efd0ee139 53 output(mcu, block, scan, value);
cgraham 0:d69efd0ee139 54 AC_count++;
cgraham 0:d69efd0ee139 55 }
cgraham 0:d69efd0ee139 56
cgraham 0:d69efd0ee139 57 void SimpleJpegDecode::outputMARK(uint8_t c)
cgraham 0:d69efd0ee139 58 {
cgraham 0:d69efd0ee139 59 }
cgraham 0:d69efd0ee139 60
cgraham 0:d69efd0ee139 61 void SimpleJpegDecode::format_YUV(int mcu, int block, int8_t* values)
cgraham 0:d69efd0ee139 62 {
cgraham 0:d69efd0ee139 63 if (block < yblock+1) {
cgraham 0:d69efd0ee139 64 memcpy(m_block_data[block], values, 64);
cgraham 0:d69efd0ee139 65 return;
cgraham 0:d69efd0ee139 66 }
cgraham 0:d69efd0ee139 67 int mcu_x_count = (width+15)/16;
cgraham 0:d69efd0ee139 68 int mcu_x = mcu % mcu_x_count;
cgraham 0:d69efd0ee139 69 int mcu_y = mcu / mcu_x_count;
cgraham 0:d69efd0ee139 70 uint8_t yuv[3];
cgraham 0:d69efd0ee139 71 if (yblock == 2) {
cgraham 0:d69efd0ee139 72 for(int y = 0; y < 8; y++) {
cgraham 0:d69efd0ee139 73 for(int x = 0; x < 16; x++) {
cgraham 0:d69efd0ee139 74 yuv[0] = m_block_data[x/8][y*8+x%8] + 128;
cgraham 0:d69efd0ee139 75 yuv[1] = m_block_data[2][y*8+x/2] + 128;
cgraham 0:d69efd0ee139 76 yuv[2] = values[y*8+x/2] + 128;
cgraham 0:d69efd0ee139 77 onResult(mcu_x * 16 + x, mcu_y * 8 + y, yuv);
cgraham 0:d69efd0ee139 78 }
cgraham 0:d69efd0ee139 79 }
cgraham 0:d69efd0ee139 80 } else if (yblock == 4) {
cgraham 0:d69efd0ee139 81 for(int y = 0; y < 16; y++) {
cgraham 0:d69efd0ee139 82 for(int x = 0; x < 16; x++) {
cgraham 0:d69efd0ee139 83 yuv[0] = m_block_data[(y/8)*2+x/8][(y%8)*8+x%8] + 128;
cgraham 0:d69efd0ee139 84 yuv[1] = m_block_data[4][(y/2)*8+x/2] + 128;
cgraham 0:d69efd0ee139 85 yuv[2] = values[(y/2)*8+x/2] + 128;
cgraham 0:d69efd0ee139 86 onResult(mcu_x * 16 + x, mcu_y * 16 + y, yuv);
cgraham 0:d69efd0ee139 87 }
cgraham 0:d69efd0ee139 88 }
cgraham 0:d69efd0ee139 89 } else {
cgraham 0:d69efd0ee139 90 ASSERT(yblock == 2 || yblock == 4);
cgraham 0:d69efd0ee139 91 }
cgraham 0:d69efd0ee139 92 }
cgraham 0:d69efd0ee139 93
cgraham 0:d69efd0ee139 94 void SimpleJpegDecode::format_RGB24(int mcu, int block, int8_t* values)
cgraham 0:d69efd0ee139 95 {
cgraham 0:d69efd0ee139 96 if (block < yblock+1) {
cgraham 0:d69efd0ee139 97 memcpy(m_block_data[block], values, 64);
cgraham 0:d69efd0ee139 98 return;
cgraham 0:d69efd0ee139 99 }
cgraham 0:d69efd0ee139 100 int mcu_x_count = (width+15)/16;
cgraham 0:d69efd0ee139 101 int mcu_x = mcu % mcu_x_count;
cgraham 0:d69efd0ee139 102 int mcu_y = mcu / mcu_x_count;
cgraham 0:d69efd0ee139 103 uint8_t rgb[3];
cgraham 0:d69efd0ee139 104 if (yblock == 2) {
cgraham 0:d69efd0ee139 105 for(int y = 0; y < 8; y++) {
cgraham 0:d69efd0ee139 106 for(int x = 0; x < 16; x++) {
cgraham 0:d69efd0ee139 107 int8_t yuv_y = m_block_data[x/8][y*8+x%8];
cgraham 0:d69efd0ee139 108 int8_t yuv_u = m_block_data[2][y*8+x/2];
cgraham 0:d69efd0ee139 109 int8_t yuv_v = values[y*8+x/2];
cgraham 0:d69efd0ee139 110 convYUVtoRGB(rgb, yuv_y, yuv_u, yuv_v);
cgraham 0:d69efd0ee139 111 onResult(mcu_x * 16 + x, mcu_y * 8 + y, rgb);
cgraham 0:d69efd0ee139 112 }
cgraham 0:d69efd0ee139 113 }
cgraham 0:d69efd0ee139 114 } else if (yblock == 4) {
cgraham 0:d69efd0ee139 115 for(int y = 0; y < 16; y++) {
cgraham 0:d69efd0ee139 116 for(int x = 0; x < 16; x++) {
cgraham 0:d69efd0ee139 117 int8_t yuv_y = m_block_data[(y/8)*2+x/8][(y%8)*8+x%8];
cgraham 0:d69efd0ee139 118 int8_t yuv_u = m_block_data[4][(y/2)*8+x/2];
cgraham 0:d69efd0ee139 119 int8_t yuv_v = values[(y/2)*8+x/2];
cgraham 0:d69efd0ee139 120 convYUVtoRGB(rgb, yuv_y, yuv_u, yuv_v);
cgraham 0:d69efd0ee139 121 onResult(mcu_x * 16 + x, mcu_y * 16 + y, rgb);
cgraham 0:d69efd0ee139 122 }
cgraham 0:d69efd0ee139 123 }
cgraham 0:d69efd0ee139 124 } else {
cgraham 0:d69efd0ee139 125 ASSERT(yblock == 2 || yblock == 4);
cgraham 0:d69efd0ee139 126 }
cgraham 0:d69efd0ee139 127 }
cgraham 0:d69efd0ee139 128
cgraham 0:d69efd0ee139 129 void SimpleJpegDecode::outputBLOCK(int mcu, int block, int8_t* values)
cgraham 0:d69efd0ee139 130 {
cgraham 0:d69efd0ee139 131 BLOCK_count++;
cgraham 0:d69efd0ee139 132 if (m_output_mode == YUV) {
cgraham 0:d69efd0ee139 133 format_YUV(mcu, block, values);
cgraham 0:d69efd0ee139 134 } else if (m_output_mode == RGB24) {
cgraham 0:d69efd0ee139 135 format_RGB24(mcu, block, values);
cgraham 0:d69efd0ee139 136 } else {
cgraham 0:d69efd0ee139 137 ASSERT(m_output_mode == YUV || m_output_mode == RGB24);
cgraham 0:d69efd0ee139 138 }
cgraham 0:d69efd0ee139 139 }
cgraham 0:d69efd0ee139 140
cgraham 0:d69efd0ee139 141 void SimpleJpegDecode::onResult(int x, int y, uint8_t* yuv)
cgraham 0:d69efd0ee139 142 {
cgraham 0:d69efd0ee139 143 if(m_pCbItem && m_pCbMeth)
cgraham 0:d69efd0ee139 144 (m_pCbItem->*m_pCbMeth)(x, y, yuv);
cgraham 0:d69efd0ee139 145 else if(m_pCb)
cgraham 0:d69efd0ee139 146 m_pCb(x, y, yuv);
cgraham 0:d69efd0ee139 147 }
cgraham 0:d69efd0ee139 148
cgraham 0:d69efd0ee139 149 void SimpleJpegDecode::setOnResult( void (*pMethod)(int, int, uint8_t*) )
cgraham 0:d69efd0ee139 150 {
cgraham 0:d69efd0ee139 151 m_pCb = pMethod;
cgraham 0:d69efd0ee139 152 m_pCbItem = NULL;
cgraham 0:d69efd0ee139 153 m_pCbMeth = NULL;
cgraham 0:d69efd0ee139 154 }
cgraham 0:d69efd0ee139 155
cgraham 0:d69efd0ee139 156 void SimpleJpegDecode::clearOnResult()
cgraham 0:d69efd0ee139 157 {
cgraham 0:d69efd0ee139 158 m_pCb = NULL;
cgraham 0:d69efd0ee139 159 m_pCbItem = NULL;
cgraham 0:d69efd0ee139 160 m_pCbMeth = NULL;
cgraham 0:d69efd0ee139 161 }