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