
BaseJpegDeocde exampe program
Dependencies: BaseJpegDecode Terminal BaseUsbHost mbed mbed-rtos
Fork of BaseJpegDecode by
Revision 5:033432f9baf3, committed 2012-11-15
- Comitter:
- va009039
- Date:
- Thu Nov 15 10:20:38 2012 +0000
- Parent:
- 4:7d88de31c55a
- Child:
- 6:95be1cd2bc14
- Commit message:
- bug fix SimpleJpegDecode.cpp
Changed in this revision
--- a/BaseJpegDecode.lib Tue Oct 30 15:35:36 2012 +0000 +++ b/BaseJpegDecode.lib Thu Nov 15 10:20:38 2012 +0000 @@ -1,1 +1,1 @@ -http://mbed.org/users/va009039/code/BaseJpegDecode/#5b1dd4e34857 +http://mbed.org/users/va009039/code/BaseJpegDecode/#a7547692071d
--- 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); } }
--- a/SimpleJpegDecode.h Tue Oct 30 15:35:36 2012 +0000 +++ b/SimpleJpegDecode.h Thu Nov 15 10:20:38 2012 +0000 @@ -4,16 +4,23 @@ #include "BaseJpegDecode.h" #include "inverseDCT.h" +#define YUV 0 +#define RGB24 1 + class SimpleJpegDecode : public BaseJpegDecode, public inverseDCT { public: - SimpleJpegDecode(); + SimpleJpegDecode(uint8_t output_mode=RGB24); + + void format_YUV(int mcu, int block, int8_t* values); + void format_RGB24(int mcu, int block, int8_t* values); + void output(int mcu, int block, int scan, int value); virtual void outputDC(int mcu, int block, int value); virtual void outputAC(int mcu, int block, int scan, int value); virtual void outputMARK(uint8_t c); - virtual void outputBLOCK(int muc, int block, uint8_t* values); // iDCT + virtual void outputBLOCK(int muc, int block, int8_t* values); // iDCT - uint8_t* m_block_data[6]; + int8_t m_block_data[5][64]; int DC_count; int AC_count; int BLOCK_count; @@ -43,6 +50,7 @@ CDummy* m_pCbItem; void (CDummy::*m_pCbMeth)(int, int, uint8_t*); void (*m_pCb)(int, int, uint8_t*); + uint8_t m_output_mode; }; #endif // SIMPLE_JPEG_DECODE_H \ No newline at end of file
--- a/bmp24.h Tue Oct 30 15:35:36 2012 +0000 +++ b/bmp24.h Thu Nov 15 10:20:38 2012 +0000 @@ -6,9 +6,12 @@ class bmp24 { public: + int width; + int height; + bmp24() { - m_width = BMP24_WIDTH; - m_height = BMP24_HEIGHT; + width = BMP24_WIDTH; + height = BMP24_HEIGHT; } void clear() { @@ -16,8 +19,8 @@ } void point(int x, int y, uint8_t* rgb) { - if (x >= 0 && x < m_width && y >= 0 && y < m_height) { - int pos = y*m_width*3+x*3; + if (x >= 0 && x < width && y >= 0 && y < height) { + int pos = y*width*3+x*3; m_bitmap[pos++] = rgb[0]; m_bitmap[pos++] = rgb[1]; m_bitmap[pos] = rgb[2]; @@ -43,21 +46,20 @@ 0x00,0x00,0x00,0x00,0x00,0x00}; int file_size = sizeof(header) + sizeof(m_bitmap); LE32write(header+2, file_size); - LE32write(header+18, m_width); - LE32write(header+22, m_height); + LE32write(header+18, width); + LE32write(header+22, height); fwrite(header, 1, sizeof(header), fp); - for(int y = m_height-1; y >=0; y--) { - for(int x = 0; x < m_width; x++) { - fputc(m_bitmap[y*m_width*3+x*3+2], fp); - fputc(m_bitmap[y*m_width*3+x*3+1], fp); - fputc(m_bitmap[y*m_width*3+x*3+0], fp); + for(int y = height-1; y >=0; y--) { + for(int x = 0; x < width; x++) { + fputc(m_bitmap[y*width*3+x*3+2], fp); + fputc(m_bitmap[y*width*3+x*3+1], fp); + fputc(m_bitmap[y*width*3+x*3+0], fp); } } fclose(fp); } - int m_width; - int m_height; + uint8_t m_bitmap[BMP24_WIDTH*BMP24_HEIGHT*3]; };
--- a/example1_c270.cpp Tue Oct 30 15:35:36 2012 +0000 +++ b/example1_c270.cpp Thu Nov 15 10:20:38 2012 +0000 @@ -1,4 +1,4 @@ -#if 0 +#if 1 // // simple color tracking // @@ -9,7 +9,10 @@ // Logitech C270 #define WIDTH 320 -#define HEIGHT 176 +//#define HEIGHT 176 + +// LifeCam +#define HEIGHT 240 #define THRESHOLD 100
--- a/example_SimpleJpegDecode.cpp Tue Oct 30 15:35:36 2012 +0000 +++ b/example_SimpleJpegDecode.cpp Thu Nov 15 10:20:38 2012 +0000 @@ -1,4 +1,4 @@ -#if 1 +#if 0 // // split jpeg to bmp files // @@ -18,32 +18,11 @@ int offset_x = 0; int offset_y = 0; -void callback(int x, int y, uint8_t* yuv) + +void callbackRGB(int x, int y, uint8_t* rgb) { led1 = !led1; if (bmp) { - uint8_t rgb[3]; - int r = yuv[0] + (yuv[2]-128) * 1.4020; - if (r < 0) { - r = 0; - } else if (r > 255) { - r = 255; - } - rgb[0] = r; - int g = yuv[0] - (yuv[1]-128) * 0.3441 - (yuv[2]-128) * 0.7139; - if (g < 0) { - g = 0; - } else if (g > 255) { - g = 255; - } - rgb[1] = g; - int b = yuv[0] + (yuv[1]-128) * 1.7718 - (yuv[2]-128) * 0.0012; - if (b < 0) { - b = 0; - } else if (b > 255) { - b = 255; - } - rgb[2] = b; bmp->point(x - offset_x, y - offset_y, rgb); } } @@ -59,34 +38,67 @@ bmp = new bmp24; ASSERT(bmp); - decode = new SimpleJpegDecode; + decode = new SimpleJpegDecode(); ASSERT(decode); - decode->setOnResult(callback); const char* input_file = "/usb/input.jpg"; - printf("input: %s\n", input_file); + + FILE *fp = fopen(input_file, "rb"); + ASSERT(fp != NULL); + Timer benchmark_t; + benchmark_t.reset(); + benchmark_t.start(); + while(!feof(fp)) { + int c = fgetc(fp); + led2 = !led2; + } + benchmark_t.stop(); + fclose(fp); + printf("input: %s, %d ms\n", input_file, benchmark_t.read_ms()); + + decode->clear(); + fp = fopen(input_file, "rb"); + ASSERT(fp != NULL); + benchmark_t.reset(); + benchmark_t.start(); + while(!feof(fp)) { + int c = fgetc(fp); + decode->input(c); + led2 = !led2; + } + benchmark_t.stop(); + fclose(fp); + printf("width: %d, height: %d, yblock: %d, %d ms\n", decode->width, decode->height, + decode->yblock, benchmark_t.read_ms()); + + decode->setOnResult(callbackRGB); int n = 0; - for(offset_y = 0; offset_y < 240; offset_y += 48) { - for(offset_x = 0; offset_x < 320; offset_x += 64) { + for(offset_y = 0; offset_y < decode->height; offset_y += bmp->height) { + for(offset_x = 0; offset_x < decode->width; offset_x += bmp->width) { bmp->clear(); decode->clear(); - FILE *fp = fopen(input_file, "rb"); + fp = fopen(input_file, "rb"); ASSERT(fp != NULL); + benchmark_t.reset(); + benchmark_t.start(); while(!feof(fp)) { int c = fgetc(fp); decode->input(c); led2 = !led2; } + benchmark_t.stop(); fclose(fp); char path[32]; sprintf(path, "/usb/output%02d.bmp", n++); - printf("offset: (%3d,%3d) %s\n", offset_x, offset_y, path); + printf("offset: (%3d,%3d), size:(%3d,%3d), %s %d ms\n", + offset_x, offset_y, bmp->width, bmp->height, + path, benchmark_t.read_ms()); bmp->writeFile(path); led3 = !led3; } led4 = !led4; } - printf("width: %d, height: %d, yblock: %d\n", decode->width, decode->height, decode->m_yblocks); + printf("done\n"); exit(1); } #endif