Chinaunix首页 | 论坛 | 博客
  • 博客访问: 2116778
  • 博文数量: 438
  • 博客积分: 3871
  • 博客等级: 中校
  • 技术积分: 6075
  • 用 户 组: 普通用户
  • 注册时间: 2011-09-10 00:11
个人简介

邮箱: wangcong02345@163.com

文章分类

全部博文(438)

文章存档

2017年(15)

2016年(119)

2015年(91)

2014年(62)

2013年(56)

2012年(79)

2011年(16)

分类: LINUX

2016-06-23 16:09:07

参照jpeg-6b/example.c这个demo可以很容易的在jpeg与bmp之间进行转换
1.将bmp转为jpg
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <setjmp.h>
  4. #include "jpeglib.h"
  5. #include <string.h>

  6. #pragma pack(1)
  7. typedef struct __BITMAPFILEHEADER__
  8. {
  9.     u_int16_t bfType;
  10.     u_int32_t bfSize;
  11.     u_int16_t bfReserved1;
  12.     u_int16_t bfReserved2;
  13.     u_int32_t bfOffBits;
  14. }BITMAPFILEHEADER;

  15. typedef struct __BITMAPINFOHEADER
  16. {
  17.     u_int32_t biSize;
  18.     u_int32_t biWidth;
  19.     u_int32_t biHeight;
  20.     u_int16_t biPlanes;
  21.     u_int16_t biBitCount;
  22.     u_int32_t biCompression;
  23.     u_int32_t biSizeImage;
  24.     u_int32_t biXPelsPerMeter;
  25.     u_int32_t biYPelsPerMeter;
  26.     u_int32_t biClrUsed;
  27.     u_int32_t biClrImportant;
  28. }BITMAPINFOHEADER;


  29. /******************** JPEG COMPRESSION SAMPLE INTERFACE *******************/

  30. /* This half of the example shows how to feed data into the JPEG compressor.
  31.  * We present a minimal version that does not worry about refinements such
  32.  * as error recovery (the JPEG code will just exit() if it gets an error).
  33.  */


  34. /*
  35.  * IMAGE DATA FORMATS:
  36.  *
  37.  * The standard input image format is a rectangular array of pixels, with
  38.  * each pixel having the same number of "component" values (color channels).
  39.  * Each pixel row is an array of JSAMPLEs (which typically are unsigned chars).
  40.  * If you are working with color data, then the color values for each pixel
  41.  * must be adjacent in the row; for example, R,G,B,R,G,B,R,G,B,... for 24-bit
  42.  * RGB color.
  43.  *
  44.  * For this example, we'll assume that this data structure matches the way
  45.  * our application has stored the image in memory, so we can just pass a
  46.  * pointer to our image buffer. In particular, let's say that the image is
  47.  * RGB color and is described by:
  48.  */
  49. #if 0
  50. extern JSAMPLE * image_buffer;    /* Points to large array of R,G,B-order data */
  51. extern int image_height;    /* Number of rows in image */
  52. extern int image_width;        /* Number of columns in image */
  53. #endif


  54. /*
  55.  * Sample routine for JPEG compression. We assume that the target file name
  56.  * and a compression quality factor are passed in.
  57.  */

  58. GLOBAL(void)
  59. write_JPEG_file (char * jpgfile, char* bmpfile, int quality)
  60. {
  61.     int w, h, bpp; //bpp-->byte_per_pix
  62.     int len;
  63.     char* image_buffer = NULL;
  64.     BITMAPFILEHEADER bmphead;
  65.     BITMAPINFOHEADER infohead;
  66.     /* This struct contains the JPEG compression parameters and pointers to
  67.      * working space (which is allocated as needed by the JPEG library).
  68.      * It is possible to have several such structures, representing multiple
  69.      * compression/decompression processes, in existence at once. We refer
  70.      * to any one struct (and its associated working data) as a "JPEG object".
  71.      */
  72.     struct jpeg_compress_struct cinfo;
  73.     /* This struct represents a JPEG error handler. It is declared separately
  74.      * because applications often want to supply a specialized error handler
  75.      * (see the second half of this file for an example). But here we just
  76.      * take the easy way out and use the standard error handler, which will
  77.      * print a message on stderr and call exit() if compression fails.
  78.      * Note that this struct must live as long as the main JPEG parameter
  79.      * struct, to avoid dangling-pointer problems.
  80.      */
  81.     struct jpeg_error_mgr jerr;
  82.     /* More stuff */
  83.     FILE * out_jpgfile;        /* target file */
  84.     FILE * in_bmpfile;        /* input file */
  85.     JSAMPROW row_pointer[1];    /* pointer to JSAMPLE row[s] */
  86.     int row_stride;        /* physical row width in image buffer */

  87.     /* Step 1: allocate and initialize JPEG compression object */

  88.     /* We have to set up the error handler first, in case the initialization
  89.      * step fails. (Unlikely, but it could happen if you are out of memory.)
  90.      * This routine fills in the contents of struct jerr, and returns jerr's
  91.      * address which we place into the link field in cinfo.
  92.      */
  93.     cinfo.err = jpeg_std_error(&jerr);
  94.     /* Now we can initialize the JPEG compression object. */
  95.     jpeg_create_compress(&cinfo);

  96.     /* Step 2: specify data destination (eg, a file) */
  97.     /* Note: steps 2 and 3 can be done in either order. */

  98.     /* Here we use the library-supplied code to send compressed data to a
  99.      * stdio stream. You can also write your own code to do something else.
  100.      * VERY IMPORTANT: use "b" option to fopen() if you are on a machine that
  101.      * requires it in order to write binary files.
  102.      */
  103.     if ((out_jpgfile = fopen(jpgfile, "wb")) == NULL) {
  104.         fprintf(stderr, "can't open jpg %s\n", jpgfile);
  105.         exit(1);
  106.     }
  107.     if ((in_bmpfile = fopen(bmpfile, "rb")) == NULL) {
  108.         fprintf(stderr, "can't open bmp=%s\n", bmpfile);
  109.         exit(1);
  110.     }
  111.     len = sizeof(bmphead)+sizeof(infohead);
  112.     printf("len=%d\n",len);
  113.     image_buffer = (char*)malloc(len*sizeof(char));
  114.     if(image_buffer == NULL)
  115.     {
  116.         printf("malloc error\n");
  117.         return ;
  118.     }
  119.     fread(image_buffer, len, 1, in_bmpfile);
  120.     memcpy(&bmphead, image_buffer, sizeof(bmphead));
  121.     memcpy(&infohead, image_buffer+sizeof(bmphead), sizeof(infohead));
  122.     if(bmphead.bfType != 0x4D42) //must be 0x4D42='BM'
  123.     {
  124.         printf("not a bmp file\n");
  125.         return ;
  126.     }
  127.     if(infohead.biBitCount != 24)  //这儿只支持bit_pre_pix=24的bmp格式
  128.     {
  129.         printf("error: now bitCount=%d not 24bit\n", infohead.biBitCount);
  130.         return ;
  131.     }
  132.     free(image_buffer);
  133.     w = infohead.biWidth;
  134.     h = infohead.biHeight;
  135.     bpp = infohead.biBitCount/8;
  136.     printf("w=%d,h=%d,bitcount=%d\n", w, h, bpp);
  137.     image_buffer = (char*)malloc(w*h*bpp);
  138.     if(image_buffer == NULL)
  139.     {
  140.         printf("malloc w*h*bpp error\n");
  141.         return ;
  142.     }
  143.     fread(image_buffer, w*h*bpp, 1, in_bmpfile);
  144.     jpeg_stdio_dest(&cinfo, out_jpgfile);

  145.     /* Step 3: set parameters for compression */

  146.     /* First we supply a description of the input image.
  147.      * Four fields of the cinfo struct must be filled in:
  148.      */
  149.     cinfo.image_width = w;     /* image width and height, in pixels */
  150.     cinfo.image_height = h;
  151.     cinfo.input_components = 3;        /* # of color components per pixel */
  152.     cinfo.in_color_space = JCS_RGB;     /* colorspace of input image */
  153.     /* Now use the library's routine to set default compression parameters.
  154.      * (You must set at least cinfo.in_color_space before calling this,
  155.      * since the defaults depend on the source color space.)
  156.      */
  157.     jpeg_set_defaults(&cinfo);
  158.     /* Now you can set any non-default parameters you wish to.
  159.      * Here we just illustrate the use of quality (quantization table) scaling:
  160.      */
  161.     jpeg_set_quality(&cinfo, quality, TRUE /* limit to baseline-JPEG values */);

  162.     /* Step 4: Start compressor */

  163.     /* TRUE ensures that we will write a complete interchange-JPEG file.
  164.      * Pass TRUE unless you are very sure of what you're doing.
  165.      */
  166.     jpeg_start_compress(&cinfo, TRUE);

  167.     /* Step 5: while (scan lines remain to be written) */
  168.     /* jpeg_write_scanlines(...); */

  169.     /* Here we use the library's state variable cinfo.next_scanline as the
  170.      * loop counter, so that we don't have to keep track ourselves.
  171.      * To keep things simple, we pass one scanline per call; you can pass
  172.      * more if you wish, though.
  173.      */
  174.     row_stride = w* 3;    /* JSAMPLEs per row in image_buffer */

  175.     while (cinfo.next_scanline < cinfo.image_height) {
  176.         /* jpeg_write_scanlines expects an array of pointers to scanlines.
  177.          * Here the array is only one element long, but you could pass
  178.          * more than one scanline at a time if that's more convenient.
  179.          */
  180.         //因为bmp图像的数据存储格式是从左下到右上,若直接处理生成的图像是倒的,所以这儿需要从下往上处理图像 
  181.         //row_pointer[0] = & image_buffer[cinfo.next_scanline * row_stride];
  182.         row_pointer[0] = & image_buffer[(cinfo.image_height-cinfo.next_scanline-1) * row_stride];
  183.         (void) jpeg_write_scanlines(&cinfo, row_pointer, 1);
  184.     }

  185.     /* Step 6: Finish compression */

  186.     jpeg_finish_compress(&cinfo);
  187.     /* After finish_compress, we can close the output file. */
  188.     fclose(out_jpgfile);
  189.     fclose(in_bmpfile);
  190.     free(image_buffer);
  191.     /* Step 7: release JPEG compression object */

  192.     /* This is an important step since it will release a good deal of memory. */
  193.     jpeg_destroy_compress(&cinfo);

  194.     /* And we're */
  195. }



  196. int main ( int argc, char *argv[] )
  197. {
  198.     char bmpfile[] = "./640_480.bmp";
  199.     char jpgfile[] = "./640_480.jpg";
  200.     write_JPEG_file(jpgfile, bmpfile, 100);
  201.     printf("read over\n");
  202.     return EXIT_SUCCESS;
  203. }



2.将jpg转为bmp
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <setjmp.h>
  4. #include "jpeglib.h"

  5. #pragma pack(1)
  6. typedef struct __BITMAPFILEHEADER__
  7. {
  8.     u_int16_t bfType;
  9.     u_int32_t bfSize;
  10.     u_int16_t bfReserved1;
  11.     u_int16_t bfReserved2;
  12.     u_int32_t bfOffBits;
  13. }BITMAPFILEHEADER;

  14. typedef struct __BITMAPINFOHEADER
  15. {
  16.     u_int32_t biSize;
  17.     u_int32_t biWidth;
  18.     u_int32_t biHeight;
  19.     u_int16_t biPlanes;
  20.     u_int16_t biBitCount;
  21.     u_int32_t biCompression;
  22.     u_int32_t biSizeImage;
  23.     u_int32_t biXPelsPerMeter;
  24.     u_int32_t biYPelsPerMeter;
  25.     u_int32_t biClrUsed;
  26.     u_int32_t biClrImportant;
  27. }BITMAPINFOHEADER;

  28. #define BYTE_PER_PIX 3
  29. int create_bmp_header(BITMAPFILEHEADER* bmphead, BITMAPINFOHEADER* infohead, int w, int h)
  30. {
  31.     bmphead->bfType = 0x4D42; //must be 0x4D42='BM'
  32.     bmphead->bfSize= w*h*BYTE_PER_PIX+14+40;
  33.     bmphead->bfReserved1= 0x00;
  34.     bmphead->bfReserved2= 0x00;
  35.     bmphead->bfOffBits = 14+40;

  36.     infohead->biSize = sizeof(BITMAPINFOHEADER);
  37.     infohead->biWidth = w;
  38.     infohead->biHeight = -h;
  39.     infohead->biPlanes = 1;
  40.     infohead->biBitCount = BYTE_PER_PIX*8;
  41.     infohead->biCompression= 0;
  42.     infohead->biSizeImage= w*h*BYTE_PER_PIX;//640 * 480 * 3;
  43.     infohead->biXPelsPerMeter= 0x0;
  44.     infohead->biYPelsPerMeter= 0x0;
  45.     infohead->biClrUsed = 0;
  46.     infohead->biClrImportant = 0;
  47.     return 0;
  48. }



  49. struct my_error_mgr {
  50.   struct jpeg_error_mgr pub;    /* "public" fields */

  51.   jmp_buf setjmp_buffer;    /* for return to caller */
  52. };

  53. typedef struct my_error_mgr * my_error_ptr;

  54. /*
  55.  * Here's the routine that will replace the standard error_exit method:
  56.  */

  57. METHODDEF(void)
  58. my_error_exit (j_common_ptr cinfo)
  59. {
  60.   /* cinfo->err really points to a my_error_mgr struct, so coerce pointer */
  61.   my_error_ptr myerr = (my_error_ptr) cinfo->err;

  62.   /* Always display the message. */
  63.   /* We could postpone this until after returning, if we chose. */
  64.   (*cinfo->err->output_message) (cinfo);

  65.   /* Return control to the setjmp point */
  66.   longjmp(myerr->setjmp_buffer, 1);
  67. }


  68. /*
  69.  * Sample routine for JPEG decompression. We assume that the source file name
  70.  * is passed in. We want to return 1 on success, 0 on error.
  71.  */

  72. int read_JPEG_file (char* bmpfile, char * jpgfile)
  73. {
  74.     BITMAPFILEHEADER bmphead;
  75.     BITMAPINFOHEADER infohead;
  76.     FILE * bmp_fp = NULL;
  77.   /* This struct contains the JPEG decompression parameters and pointers to
  78.    * working space (which is allocated as needed by the JPEG library).
  79.    */
  80.   struct jpeg_decompress_struct cinfo;
  81.   /* We use our private extension JPEG error handler.
  82.    * Note that this struct must live as long as the main JPEG parameter
  83.    * struct, to avoid dangling-pointer problems.
  84.    */
  85.   struct my_error_mgr jerr;
  86.   /* More stuff */
  87.   FILE * jpg_file;        /* source file */
  88.   JSAMPARRAY buffer;        /* Output row buffer */
  89.   int row_stride;        /* physical row width in output buffer */

  90.   /* In this example we want to open the input file before doing anything else,
  91.    * so that the setjmp() error recovery below can assume the file is open.
  92.    * VERY IMPORTANT: use "b" option to fopen() if you are on a machine that
  93.    * requires it in order to read binary files.
  94.    */

  95.   if ((jpg_file= fopen(jpgfile, "rb")) == NULL) {
  96.     fprintf(stderr, "can't open jpgfile=%s\n", jpgfile);
  97.     return 0;
  98.   }

  99.   //prepare for bmp write
  100.   if (NULL == (bmp_fp = fopen(bmpfile,"wb")))
  101.   {
  102.      fprintf(stderr, "can't open bmpfile=%s\n", bmpfile);
  103.       return -1;
  104.   }

  105.   /* Step 1: allocate and initialize JPEG decompression object */

  106.   /* We set up the normal JPEG error routines, then override error_exit. */
  107.   cinfo.err = jpeg_std_error(&jerr.pub);
  108.   jerr.pub.error_exit = my_error_exit;
  109.   /* Establish the setjmp return context for my_error_exit to use. */
  110.   if (setjmp(jerr.setjmp_buffer)) {
  111.     /* If we get here, the JPEG code has signaled an error.
  112.      * We need to clean up the JPEG object, close the input file, and return.
  113.      */
  114.     jpeg_destroy_decompress(&cinfo);
  115.     fclose(jpg_file);
  116.     return 0;
  117.   }
  118.   /* Now we can initialize the JPEG decompression object. */
  119.   jpeg_create_decompress(&cinfo);

  120.   /* Step 2: specify data source (eg, a file) */

  121.   jpeg_stdio_src(&cinfo, jpg_file);

  122.   /* Step 3: read file parameters with jpeg_read_header() */

  123.   (void) jpeg_read_header(&cinfo, TRUE);
  124.   printf("w=%d,h=%d\n", cinfo.image_width, cinfo.image_height);

  125.   create_bmp_header(&bmphead, &infohead, cinfo.image_width, cinfo.image_height);
  126.   fwrite(&bmphead, 14, 1, bmp_fp);
  127.   fwrite(&infohead, 40, 1, bmp_fp);
  128.   /* We can ignore the return value from jpeg_read_header since
  129.    * (a) suspension is not possible with the stdio data source, and
  130.    * (b) we passed TRUE to reject a tables-only JPEG file as an error.
  131.    * See libjpeg.doc for more info.
  132.    */

  133.   /* Step 4: set parameters for decompression */

  134.   /* In this example, we don't need to change any of the defaults set by
  135.    * jpeg_read_header(), so we do nothing here.
  136.    */

  137.   /* Step 5: Start decompressor */

  138.   (void) jpeg_start_decompress(&cinfo);
  139.   /* We can ignore the return value since suspension is not possible
  140.    * with the stdio data source.
  141.    */

  142.   /* We may need to do some setup of our own at this point before reading
  143.    * the data. After jpeg_start_decompress() we have the correct scaled
  144.    * output image dimensions available, as well as the output colormap
  145.    * if we asked for color quantization.
  146.    * In this example, we need to make an output work buffer of the right size.
  147.    */
  148.   /* JSAMPLEs per row in output buffer */
  149.   row_stride = cinfo.output_width * cinfo.output_components;
  150.   /* Make a one-row-high sample array that will go away when done with image */
  151.   buffer = (*cinfo.mem->alloc_sarray)
  152.         ((j_common_ptr) &cinfo, JPOOL_IMAGE, row_stride, 1);

  153.   /* Step 6: while (scan lines remain to be read) */
  154.   /* jpeg_read_scanlines(...); */

  155.   /* Here we use the library's state variable cinfo.output_scanline as the
  156.    * loop counter, so that we don't have to keep track ourselves.
  157.    */
  158.   while (cinfo.output_scanline < cinfo.output_height) {
  159.     /* jpeg_read_scanlines expects an array of pointers to scanlines.
  160.      * Here the array is only one element long, but you could ask for
  161.      * more than one scanline at a time if that's more convenient.
  162.      */
  163.     (void) jpeg_read_scanlines(&cinfo, buffer, 1);
  164.     /* Assume put_scanline_someplace wants a pointer and sample count. */
  165.     //put_scanline_someplace(buffer[0], row_stride);
  166.     fwrite(buffer[0],row_stride,1, bmp_fp);
  167.   }
  168.   fclose(bmp_fp);

  169.   /* Step 7: Finish decompression */

  170.   (void) jpeg_finish_decompress(&cinfo);
  171.   /* We can ignore the return value since suspension is not possible
  172.    * with the stdio data source.
  173.    */

  174.   /* Step 8: Release JPEG decompression object */

  175.   /* This is an important step since it will release a good deal of memory. */
  176.   jpeg_destroy_decompress(&cinfo);

  177.   /* After finish_decompress, we can close the input file.
  178.    * Here we postpone it until after no more JPEG errors are possible,
  179.    * so as to simplify the setjmp error logic above. (Actually, I don't
  180.    * think that jpeg_destroy can do an error exit, but why assume anything...)
  181.    */
  182.   fclose(jpg_file);

  183.   /* At this point you may want to check to see whether any corrupt-data
  184.    * warnings occurred (test whether jerr.pub.num_warnings is nonzero).
  185.    */

  186.   /* And we're */
  187.   return 1;
  188. }


  189. int main ( int argc, char *argv[] )
  190. {
  191.     //char filename[] = "./testimg.jpg";
  192.     char jpgfile[] = "./640_480.jpg";
  193.     char bmpfile[] = "./640_480.bmp";
  194.     read_JPEG_file(bmpfile, jpgfile);
  195.     printf("read over\n");
  196.     return EXIT_SUCCESS;
  197. }




阅读(4041) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~