Any changes are to allow conversion to BMP

Dependencies:   BaseJpegDecode Camera_LS_Y201 Motordriver Servo mbed

Fork of Bitmap_copy_copy by Eric Wieser

Committer:
kylepost3
Date:
Wed Apr 30 14:19:33 2014 +0000
Revision:
1:d721e32cf79c
Final design project for ECE 4180.  The device takes scans left to right taking pictures (In JPEG), converts the picture to BMP, and scans for red pixels.  When the threshold of red pixels is reached, it fires the catapult and reloads.

Who changed what in which revision?

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