赞
踩
在做算法的过程中经常终端传来的是jpeg图片,需要将jpeg解码为yuv再进行处理。这里使用jpeg-6b交叉编译,然后进行解码,下面是解码的过程:
#include <ctype.h> #include <errno.h> #include <unistd.h> #include <setjmp.h> #include <sys/stat.h> #include <stdio.h> #include <string.h> #include <time.h> #include <stdlib.h> #include <string.h> #include "jpeglib.h" #include <setjmp.h> #include "decode.h" struct my_error_mgr { struct jpeg_error_mgr pub; /* "public" fields */ jmp_buf setjmp_buffer; /* for return to caller */ }; typedef struct my_error_mgr * my_error_ptr; void my_decompress_error_exit (j_common_ptr cinfo) { /* cinfo->err really points to a my_error_mgr struct, so coerce pointer */ my_error_ptr myerr = (my_error_ptr) cinfo->err; /* Always display the message. */ /* We could postpone this until after returning, if we chose. */ (*cinfo->err->output_message) (cinfo); /* Return control to the setjmp point */ longjmp(myerr->setjmp_buffer, 1); } int decode_jpeg_file (char *frame,int frame_size,char *decoded_frame,int *decoded_frame_size,int *decoded_width,int *decoded_height,int color_space) { struct jpeg_decompress_struct cinfo; struct my_error_mgr jerr; FILE *infile, *outfile; JSAMPARRAY buffer; /* Output row buffer */ int row_stride; /* physical row width in output buffer */ int finished = 1; int chromaWidth, chromaHeight; int yMask,xMask; int x,y; int width,height; unsigned char *pixels=NULL,*rgbPixels=NULL, *src=NULL; unsigned char *yPixels=NULL, *uPixels=NULL, *vPixels=NULL; unsigned char *yPtr=NULL, *uPtr=NULL, *vPtr=NULL; cinfo.err = jpeg_std_error(&jerr.pub); jerr.pub.error_exit = my_decompress_error_exit; if (setjmp(jerr.setjmp_buffer)) { jpeg_destroy_decompress(&cinfo); //fclose(infile); return -1; } jpeg_create_decompress(&cinfo); //jpeg_stdio_src(&cinfo, infile); jpeg_stdio_buffer_src(&cinfo,(unsigned char *)(frame),frame_size); (void) jpeg_read_header(&cinfo, TRUE); /*set parameters for decompression */ cinfo.out_color_space = JCS_YCbCr; (void) jpeg_start_decompress(&cinfo); width = cinfo.output_width; height = cinfo.output_height; *decoded_width = width; *decoded_height = height; pixels = (unsigned char *)malloc(width*height*3); if(pixels==NULL) printf("Malloc pixels failed!!!!\n"); memset(pixels, 0, width * height * 3); src = rgbPixels = pixels; /* JSAMPLEs per row in output buffer */ row_stride = cinfo.output_width * cinfo.output_components; /* Make a one-row-high sample array that will go away when done with image */ buffer = (*cinfo.mem->alloc_sarray)((j_common_ptr) &cinfo, JPOOL_IMAGE, row_stride, 1); printf("cinfo.output_width:%d\n",cinfo.output_width); printf("cinfo.output_height:%d\n",cinfo.output_height); printf("cinfo.output_components:%d\n",cinfo.output_components); while (cinfo.output_scanline < cinfo.output_height) { int num_rows = jpeg_read_scanlines(&cinfo, buffer, 1); // printf("cinfo.output_scanline:%d\n",cinfo.output_scanline); // printf("num_rows:%d\n",num_rows); // printf("\t\tcinfo.output_components:%d\n",cinfo.output_components); // getchar(); if (num_rows == 0) { finished = 0; break; } if (cinfo.output_components == 1) { // greyscale unsigned int i; unsigned char *in = (unsigned char *)(*buffer); for (i = 0; i < width * num_rows; ++i) { *pixels++ = *in; // red b *pixels++ = *in; // green g *pixels++ = *in; // blue r ++in; } } else if (cinfo.output_components == 3) { // RGB memcpy(rgbPixels, (*buffer), num_rows * width * 3); rgbPixels += num_rows * width * 3; //memcpy(pixels, (*buffer), num_rows * width * 3); //pixels += num_rows * width * 3; } } rgbPixels = pixels; if(finished) { printf("jpeg_finish_decompress!\n"); (void) jpeg_finish_decompress(&cinfo); } printf("\n"); jpeg_destroy_decompress(&cinfo); printf("jpeg_destroy_decompress finished! \n"); // fwrite(yPixels, 1, width * height, outfile); // fwrite(uPixels, 1, chromaWidth*chromaHeight, outfile); // fwrite(vPixels, 1, chromaWidth*chromaHeight, outfile); // fwrite(rgbPixels, 1, width * height*3, outfile); //if( NULL !=infile) //{ // fclose(infile); //} //if(NULL != outfile) //{ // fclose(outfile); //} /* if(width!=352||height!=288) { printf("Decoded img:wid=%d,hgt=%d\tError!!!!!!!not 352*288!!!!\n",width,height); return -1; } else */ if (color_space == DECODE_COLOR_Y||color_space == DECODE_COLOR_GRAY) { yPixels = (unsigned char*)malloc(height * width); if(yPixels==NULL)printf("Malloc yPixels fail!!!\n"); yPtr = yPixels; for(y = 0; y < height; y++) { for(x = 0; x < width; x++) { *yPtr++ = *rgbPixels++; rgbPixels += 2; } } memcpy(decoded_frame, yPixels, height * width ); *decoded_frame_size = height * width; } else if (color_space == DECODE_COLOR_YUV420) { chromaWidth = width/2; chromaHeight = height/2; printf("color_space DECODE_COLOR_YUV420! \n"); yMask = xMask = 1; yPixels = (unsigned char*)malloc(width * height); if(yPixels==NULL)printf("Malloc yPixels fail!!!\n"); uPixels = (unsigned char*)malloc(chromaWidth*chromaHeight); if(uPixels==NULL)printf("Malloc uPixels fail!!!\n"); vPixels = (unsigned char*)malloc(chromaWidth*chromaHeight); if(vPixels==NULL)printf("Malloc vPixels fail!!!\n"); yPtr = yPixels; uPtr = uPixels; vPtr = vPixels; for(y = 0; y < height; y++) { for(x = 0; x < width; x++) { *yPtr++ = *rgbPixels++; if((y & yMask) == 0 && (x & xMask) == 0) { *uPtr++ = *rgbPixels++; *vPtr++ = *rgbPixels++; } else { rgbPixels += 2; } } } memcpy(decoded_frame, yPixels, height * width ); memcpy(decoded_frame+height * width, uPixels, chromaHeight * chromaWidth ); memcpy(decoded_frame+height * width+chromaHeight * chromaWidth, vPixels, chromaHeight * chromaWidth ); *decoded_frame_size = height * width/2*3; printf("decoded_frame:%d\n", *decoded_frame_size); rgbPixels=NULL; } else if (color_space == DECODE_COLORYUV444) { chromaWidth = width; chromaHeight = height; yPixels = (unsigned char*)malloc(height * width); if(yPixels==NULL)printf("Malloc yPixels fail!!!\n"); uPixels = (unsigned char*)malloc(chromaWidth*chromaHeight); if(uPixels==NULL)printf("Malloc uPixels fail!!!\n"); vPixels = (unsigned char*)malloc(chromaWidth*chromaHeight); if(vPixels==NULL)printf("Malloc vPixels fail!!!\n"); yPtr = yPixels; uPtr = uPixels; vPtr = vPixels; for(y = 0; y < height; y++) { for(x = 0; x < width; x++) { *yPtr++ = *rgbPixels++; *uPtr++ = *rgbPixels++; *vPtr++ = *rgbPixels++; } } memcpy(decoded_frame, yPixels, height * width ); memcpy(decoded_frame+height * width, uPixels, height * width ); memcpy(decoded_frame+2*height * width, vPixels, height * width ); *decoded_frame_size = height * width*3; } if( NULL !=pixels) { free(pixels); pixels = NULL; } if( NULL !=yPixels) { free(yPixels); yPixels = NULL; } if( NULL !=uPixels) { free(uPixels); uPixels = NULL; } if( NULL !=vPixels) { free(vPixels); vPixels = NULL; } if( NULL !=rgbPixels) { rgbPixels = NULL; } return 0; }
需要注意的是,jpeg-6b解码好像只能用gcc编译,用g++会出错,我通常是将其封装成库,用gcc编译,然后在c++中调用。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。