int jpeg_encode(unsigned char* in_buf, unsigned char* out_buf) { unsigned char block[BLOCK_SIZE * BLOCK_SIZE]; short block_o[BLOCK_SIZE * BLOCK_SIZE]; init_buf(out_buf); huffman_start(IMAGE_HEIGHT, IMAGE_WIDTH, Y_IMAGE, quality); unsigned y, x; for (y = 0; y < IMAGE_HEIGHT; y += 8) { for (x = 0; x < IMAGE_WIDTH; x += 8) { get_block(x, y, 8, 8, in_buf, block); dct3(block, block_o); block_o[0] -= 1024; huffman_encode(HUFFMAN_CTX_Y, block_o); } } huffman_stop(); return get_size(); }
int main(void) { /*!< At this stage the microcontroller clock setting is already configured, this is done through SystemInit() function which is called from startup file (startup_stm32f4xx.s) before to branch to application main. To reconfigure the default setting of SystemInit() function, refer to system_stm32f4xx.c file */ /* SysTick end of count event each 10ms */ unsigned int line; enum { TYPE_UNKNOWN=0, TYPE_RGB24, TYPE_RGB16, TYPE_YUV, } image_type = TYPE_UNKNOWN; RCC_GetClocksFreq(&RCC_Clocks); SysTick_Config(RCC_Clocks.HCLK_Frequency / 100); init_USART1(1048576); USART_puts(USART2,"\nLoaded,"); image_type = TYPE_YUV; frame_done=0; // LIS302DL_Reset(); /* SET USER Key */ /* Configure EXTI Line0 (connected to PA0 pin) in interrupt mode */ // EXTILine0_Config(); // /* Initialize the LCD */ // STM32f4_Discovery_LCD_Init(); // LCD_Clear(LCD_COLOR_WHITE); // LCD_SetTextColor(LCD_COLOR_BLUE); // DCMI_Control_IO_Init();//funtion to configure reset and power pins of the camera **dont need for tw9910 // LCD_DisplayStringLine(LINE(2), " Camera Init.."); /* OV9655 Camera Module configuration */ // ****INIT the TW9910 in the following function if (DCMI_OV9655Config() == 0x00)//configures pins of DCMI,I2C and DMA and the camera settings, if it returns a positive response { //Successful // int fr=0; USART_puts(USART2,"In TW9910\n"); // LCD_DisplayStringLine(LINE(2), " "); // LCD_SetDisplayWindow(0, 0, 320, 240); // LCD_WriteRAM_Prepare(); //initialise an array here for the Image and ensure it is set up in the DMA configuration /* Enable DMA transfer */ DMA_Cmd(DMA2_Stream1, ENABLE); /* Enable DCMI interface */ DCMI_Cmd(ENABLE); /* Start Image capture */ DCMI_CaptureCmd(ENABLE); /*init the picture count*/ //useless for tw9910 and our case //init_picture_count(); // a function to initialise a variable from a counter file in the sdcard to name the new bmp file and file-xxx.bmp while (1) { // int i; //Delay(50); // int i; //for(i=0;i<1000;i++); if (frame_done) { // char s[5]; // fr++; // USART_puts(USART2,"\nNewFrame\n"); // if (capture_Flag == ENABLE) { DCMI_CaptureCmd(DISABLE); USART_puts(USART2,"\njpeg2\n"); huffman_start(IMG_HEIGHT & -8, IMG_WIDTH & -8); huffman_resetdc(); // USART_puts(USART2,"\njpeg\n"); // // for(i=0;i<FULLIMAGESIZE;i++){ // sprintf(s,",%x",imagearray[i]); // USART_puts(USART2,s); // //USART_writebyte(USART2,&imagearray[i]); // // } // // USART_puts(USART2,"\nDone"); // capture_Flag = DISABLE; // // Capture_Image_TO_Bmp(); //// LCD_SetDisplayWindow(0, 0, 320, 240); //// LCD_WriteRAM_Prepare(); // capture_Flag = ENABLE; // } // USART_puts(USART2,"\njpeg2\n"); for (line=0; line<NUM_LINES; line++) { uint8_t* line_buffer=(uint8_t *)&(imagearray[line*(IMG_WIDTH*IMG_HEIGHT*2/NUM_LINES)]); // encode the line using appropriate encoder switch (image_type) { // case TYPE_RGB24: encode_line_rgb24(line_buffer, line); break; // case TYPE_RGB16: encode_line_rgb16(line_buffer, line); break; case TYPE_YUV: encode_line_yuv(line_buffer, line); break; case TYPE_UNKNOWN: default:break; // fprintf(stderr, "error: %s, unsupported encoder for input '%s'\n", argv[0], argv[1]); // exit(1); } } // write .jpeg footer (end-of-image marker) huffman_stop(); USART_puts(USART2,"\njpegends\n"); DCMI_CaptureCmd(ENABLE); frame_done = 0; //if(fr==2) //while(1); } } } else { // LCD_SetTextColor(LCD_COLOR_RED); // LCD_DisplayStringLine(LINE(2), "Camera Init.. fails"); // LCD_DisplayStringLine(LINE(4), "Check the Camera HW "); // LCD_DisplayStringLine(LINE(5), " and try again "); /* Go to infinite loop */ while (1); } }
int main(void) { /*!< At this stage the microcontroller clock setting is already configured, this is done through SystemInit() function which is called from startup file (startup_stm32f4xx.s) before to branch to application main. To reconfigure the default setting of SystemInit() function, refer to system_stm32f4xx.c file */ /* SysTick end of count event each 10ms */ #ifndef YUVDEBUG unsigned int line; #endif RCC_GetClocksFreq(&RCC_Clocks); SysTick_Config(RCC_Clocks.HCLK_Frequency / 100); init_USART1(1048576); USART_puts(USART2,"\nLoaded,"); frame_done=0; /*Camera configuration */ // ****INIT the TW9910 in the following function if (DCMI_OV9655Config() == 0x00)//configures pins of DCMI,I2C and DMA and the camera settings, if it returns a positive response { //Successful int fr=0; USART_puts(USART2,"In TW9910\n"); /* Enable DMA transfer */ DMA_Cmd(DMA2_Stream1, ENABLE); /* Enable DCMI interface */ DCMI_Cmd(ENABLE); /* Start Image capture */ DCMI_CaptureCmd(ENABLE); while (1) { // int i; // Delay(50); if (frame_done) { char s[5]; int i; fr++; DCMI_CaptureCmd(DISABLE); #ifndef YUVDEBUG USART_puts(USART2,"\njpeg2\n"); huffman_start(IMG_HEIGHT & -8, IMG_WIDTH & -8); huffman_resetdc(); #endif #ifdef YUVDEBUG USART_puts(USART2,"\nNewFrame\n"); for(i=0;i<FULLIMAGESIZE*2;i++){ sprintf(s,",%x",imagearray[i]); USART_puts(USART2,s); } #endif #ifndef YUVDEBUG for (line=0; line<NUM_LINES; line++) { uint8_t* line_buffer=(uint8_t *)&(imagearray[line*(IMG_WIDTH*8*2)]); // encode the line using encoder encode_line_yuv(line_buffer, line); } // write .jpeg footer (end-of-image marker) huffman_stop(); #endif // /* print the frame counter */ // sprintf(s,",%d",fr); // USART_puts(USART2,s); //USART_puts(USART2,"\njpegends\n"); DCMI_CaptureCmd(ENABLE); frame_done = 0; } } } else {// Cant INIT the TW9910 USART_puts(USART2,"Cant Init TW9910"); /* Go to infinite loop */ while (1); } }
int main (int argc, char *argv[]) { if (argc < 3) { fprintf(stderr, "Usage: %s file-in.[rgb|rgb16|yuv] file-out.jpg\n", argv[0]); return -1; } // image type enum { TYPE_UNKNOWN=0, TYPE_RGB24, TYPE_RGB16, TYPE_YUV, } image_type = TYPE_UNKNOWN; unsigned int line_size = 0; // get image type from filename extension char * ext = strpbrk(argv[1],"."); if (ext == NULL ) image_type = TYPE_UNKNOWN; else if (strcmp(ext,".rgb24")==0) image_type = TYPE_RGB24; else if (strcmp(ext,".rgb16")==0) image_type = TYPE_RGB16; else if (strcmp(ext,".yuv") ==0) image_type = TYPE_YUV; else image_type = TYPE_UNKNOWN; switch (image_type) { case TYPE_RGB24: line_size = 15360; break; case TYPE_RGB16: line_size = 10240; break; #ifndef GRAYSCALE case TYPE_YUV: line_size = IMG_WIDTH*2*8 /* 10240 for 640*480 */; break; #endif #ifdef GRAYSCALE case TYPE_YUV: line_size = IMG_WIDTH*8; break; #endif case TYPE_UNKNOWN: default: fprintf(stderr, "error: %s, unknown file type for input '%s'\n", argv[0], argv[1]); exit(1); } // try to open input file for reading FILE * file_rgb = fopen(argv[1], "rb"); if (!file_rgb) { fprintf(stderr, "error: %s, cannot open '%s' for reading\n", argv[0], argv[1]); exit(1); } // try to open output file for writing file_jpg = fopen(argv[2], "wb"); if (!file_rgb) { fprintf(stderr, "error: %s, cannot open '%s' for writing\n", argv[0], argv[2]); fclose(file_rgb); exit(1); } // line buffer uint8_t line_buffer[line_size]; // write .jpeg header and start-of-image marker huffman_start(IMG_HEIGHT & -8, IMG_WIDTH & -8); huffman_resetdc(); // try to load data from file one line at a time // number of lines in image (specific to 640 x 480 image and encoding rate) unsigned int line; for (line=0; line<NUM_LINES; line++) { // load line from input int num_read = fread(line_buffer, sizeof(uint8_t), line_size, file_rgb); // ensure data are read properly // TODO: check for premature end of file if (num_read != line_size) { fprintf(stderr,"error: %s, could not read data from input file (got %d bytes, expected %u)\n", argv[0], num_read, line_size); fclose(file_rgb); fclose(file_jpg); exit(1); } // encode the line using appropriate encoder switch (image_type) { case TYPE_RGB24: encode_line_rgb24(line_buffer, line); break; case TYPE_RGB16: encode_line_rgb16(line_buffer, line); break; case TYPE_YUV: encode_line_yuv(line_buffer, line); break; case TYPE_UNKNOWN: default: fprintf(stderr, "error: %s, unsupported encoder for input '%s'\n", argv[0], argv[1]); exit(1); } } // write .jpeg footer (end-of-image marker) huffman_stop(); // close input/output files fclose(file_rgb); fclose(file_jpg); // return successfully return 0; }
int main (int argc, char *argv[]) { CBitmap bmp; #ifdef INVERSE FILE *fileY = fopen("dump.y.bin", "wb"); FILE *fileCb = fopen("dump.cb.bin", "wb"); FILE *fileCr = fopen("dump.cr.bin", "wb"); #endif //unsigned i; if (argc < 3) { fprintf(stderr, "Usage: %s file-in.bmp file-out.jpg\n", argv[0]); return -1; } if (!bmp.Load(argv[1])) { fprintf(stderr, "Error: cannot open %s\n", argv[1]); return -1; } if (bmp.GetBitCount() != 24) { fprintf(stderr, "Error BitCount != 24\n"); return -1; } /*recalc_qtab(512, qtable_paint_lum, 0); recalc_qtab(1024, qtable_paint_lum, 1); recalc_qtab(512, qtable_paint_chrom, 0); recalc_qtab(1024, qtable_paint_chrom, 1);*/ BGR RGB16x16[16][16]; CACHE_ALIGN conv Y8x8[2][2][8][8]; // four 8x8 blocks - 16x16 CACHE_ALIGN conv Cb8x8[8][8]; CACHE_ALIGN conv Cr8x8[8][8]; //dct_fill_tab(); // for IDCT if ((file_jpg = open(argv[2], O_CREAT|O_TRUNC|O_WRONLY|O_BINARY, S_IWRITE)) < 0) { fprintf(stderr, "Error: cannot create %s (%s)\n", argv[2], strerror(errno)); return -1; } uint64_t tm = __rdtsc(); // Process image by 16x16 blocks, (16x16 because of chroma subsampling) // The resulting image will be truncated on the right/down side // if its width/height is not multiple of 16. // The data is written into <file_jpg> file by write_jpeg() function // which Huffman encoder uses to flush its output, so this file // should be opened before the call of huffman_start(). huffman_start(bmp.GetHeight() & -16, bmp.GetWidth() & -16); for (unsigned y = 0; y < bmp.GetHeight()-15; y += 16) { for (unsigned x = 0; x < bmp.GetWidth()-15; x += 16) { if (!bmp.GetBlock(x, y, 16, 16, (BGR*)RGB16x16)) { printf("Error: getBlock(%d,%d)\n", x, y); break; } /* // geting four 8x8 Y-blocks for (unsigned i = 0; i < 2; i++) for (unsigned j = 0; j < 2; j++) { for (unsigned r = 0; r < 8; r++) for (unsigned c = 0; c < 8; c++) { const unsigned rr = (i<<3) + r; const unsigned cc = (j<<3) + c; const color R = RGB16x16[rr][cc].Red; const color G = RGB16x16[rr][cc].Green; const color B = RGB16x16[rr][cc].Blue; // converting RGB into Y (luminance) Y8x8[i][j][r][c] = RGB2Y(R, G, B)-128; } } // getting subsampled Cb and Cr subsample(RGB16x16, Cb8x8, Cr8x8); */ // getting subsampled Cb and Cr subsample2(RGB16x16, Y8x8, Cb8x8, Cr8x8); uint64_t tmj = __rdtsc(); // 1 Y-compression dct3(Y8x8[0][0], Y8x8[0][0]); //quantization_lum(Y8x8[0][0]); huffman_encode(HUFFMAN_CTX_Y, (conv*)Y8x8[0][0]); // 2 Y-compression dct3(Y8x8[0][1], Y8x8[0][1]); //quantization_lum(Y8x8[0][1]); huffman_encode(HUFFMAN_CTX_Y, (conv*)Y8x8[0][1]); // 3 Y-compression dct3(Y8x8[1][0], Y8x8[1][0]); //quantization_lum(Y8x8[1][0]); huffman_encode(HUFFMAN_CTX_Y, (conv*)Y8x8[1][0]); // 4 Y-compression dct3(Y8x8[1][1], Y8x8[1][1]); //quantization_lum(Y8x8[1][1]); huffman_encode(HUFFMAN_CTX_Y, (conv*)Y8x8[1][1]); // Cb-compression dct3(Cb8x8, Cb8x8); //quantization_chrom(Cb8x8); huffman_encode(HUFFMAN_CTX_Cb, (conv*)Cb8x8); // Cr-compression dct3(Cr8x8, Cr8x8); //quantization_chrom(Cr8x8); huffman_encode(HUFFMAN_CTX_Cr, (conv*)Cr8x8); jpgclk += __rdtsc() - tmj; #ifdef INVERSE quantization_lum(Y8x8[0][0]); quantization_lum(Y8x8[0][1]); quantization_lum(Y8x8[1][0]); quantization_lum(Y8x8[1][1]); quantization_chrom(Cb8x8); quantization_chrom(Cr8x8); dump((conv*)Y8x8[0][0], fileY); dump((conv*)Y8x8[0][1], fileY); dump((conv*)Y8x8[1][0], fileY); dump((conv*)Y8x8[1][1], fileY); dump((conv*)Cb8x8, fileCb); dump((conv*)Cr8x8, fileCr); // inverse DCTs - getting pixels back iquantization_lum(Y8x8[0][0]); idct3(Y8x8[0][0], Y8x8[0][0]); //correct_color(Y8x8[0][0]); iquantization_lum(Y8x8[0][1]); idct3(Y8x8[0][1], Y8x8[0][1]); //correct_color(Y8x8[0][1]); iquantization_lum(Y8x8[1][0]); idct3(Y8x8[1][0], Y8x8[1][0]); //correct_color(Y8x8[1][0]); iquantization_lum(Y8x8[1][1]); idct3(Y8x8[1][1], Y8x8[1][1]); //correct_color(Y8x8[1][1]); iquantization_chrom(Cb8x8); idct3(Cb8x8, Cb8x8); //correct_color(Cb8x8); iquantization_chrom(Cr8x8); idct3(Cr8x8, Cr8x8); //correct_color(Cr8x8); for (unsigned i = 0; i < 2; i++) for (unsigned j = 0; j < 2; j++) { for (unsigned r = 0; r < 8; r += 2) for (unsigned c = 0; c < 8; c += 2) { const unsigned rr = (i<<3) + r; const unsigned cc = (j<<3) + c; // convert pixels back into RGB const conv Cb = Cb8x8[rr>>1][cc>>1] + 128; const conv Cr = Cr8x8[rr>>1][cc>>1] + 128; conv Y; Y = Y8x8[i][j][r][c] + 128; RGB16x16[rr][cc].Red = YCbCr2R(Y, Cb, Cr); RGB16x16[rr][cc].Green = YCbCr2G(Y, Cb, Cr); RGB16x16[rr][cc].Blue = YCbCr2B(Y, Cb, Cr); Y = Y8x8[i][j][r][c+1] + 128; RGB16x16[rr][cc+1].Red = YCbCr2R(Y, Cb, Cr); RGB16x16[rr][cc+1].Green = YCbCr2G(Y, Cb, Cr); RGB16x16[rr][cc+1].Blue = YCbCr2B(Y, Cb, Cr); Y = Y8x8[i][j][r+1][c] + 128; RGB16x16[rr+1][cc].Red = YCbCr2R(Y, Cb, Cr); RGB16x16[rr+1][cc].Green = YCbCr2G(Y, Cb, Cr); RGB16x16[rr+1][cc].Blue = YCbCr2B(Y, Cb, Cr); Y = Y8x8[i][j][r+1][c+1] + 128; RGB16x16[rr+1][cc+1].Red = YCbCr2R(Y, Cb, Cr); RGB16x16[rr+1][cc+1].Green = YCbCr2G(Y, Cb, Cr); RGB16x16[rr+1][cc+1].Blue = YCbCr2B(Y, Cb, Cr); } } // save pixels if (!bmp.SetBlock(x, y, 16, 16, (BGR*)RGB16x16)) { printf("Error: SetBlock(%d,%d)\n", x, y); } #endif } } huffman_stop(); tm = __rdtsc() - tm; close(file_jpg); printf(" DCT MIPS:\t\t%f\n", dctclk/1.e6); printf("JPEG MIPS:\t\t%f\n", jpgclk/1.e6); printf("IDCT MIPS(SSE2):\t%f\n", idctclk/1.e6); printf(" ALL MIPS:\t\t%f\n", tm/1.e6); #ifdef INVERSE bmp.Save("testz.bmp"); fclose(fileY); fclose(fileCb); fclose(fileCr); #endif return 0; }