test
Dependencies: Nanopb iSerial mbed BaseJpegDecode FatFileSystem SDFileSystem RingBuffer Camera_LS_Y201
extlib/SimpleJpegDecode/SimpleJpegDecode.cpp@0:d69efd0ee139, 2014-09-18 (annotated)
- Committer:
- cgraham
- Date:
- Thu Sep 18 15:21:47 2014 +0000
- Revision:
- 0:d69efd0ee139
test
Who changed what in which revision?
User | Revision | Line number | New 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 | } |