zoukankan      html  css  js  c++  java
  • libJPEG-turbo库使用示例代码

     libJPEG库是用于编码数据为JPEG格式或者解码JPEG格式图片的常用库,OpenCV读取图像底层实现就是利用libJPEG库,而libJPEG-turbo则效率更高。

    具体怎么编译编译libJPEG库源码得到lib库的方法很容易搜到,不多做介绍。

    下面的代码包含了该库中常用的API用法,包括读取一幅JPEG图片并解码到内存、编码内存中的数据为JPEG图片写入本地等。

      1 #include <iostream>  
      2 #include <stdio.h>  
      3 #include <setjmp.h>  
      4 #include <string.h>  
      5 #include <stdlib.h>  
      6 #include <jpeglib.h>
      7 #include <opencv2/opencv.hpp>
      8 
      9 using namespace std;
     10 
     11 int read_JPEG_file(string strImageName)
     12 {
     13     /* This struct contains the JPEG decompression parameters and pointers to
     14     * working space (which is allocated as needed by the JPEG library).
     15     */
     16     struct jpeg_decompress_struct cinfo;
     17     /* We use our private extension JPEG error handler.
     18     * Note that this struct must live as long as the main JPEG parameter
     19     * struct, to avoid dangling-pointer problems.
     20     */
     21     struct jpeg_error_mgr jerr;
     22     /* More stuff */
     23     FILE * infile;/* source file */
     24     JSAMPARRAY buffer;/* Output row buffer */
     25     int row_stride;/* physical row width in output buffer */
     26 
     27                    /* In this example we want to open the input file before doing anything else,
     28                    * so that the setjmp() error recovery below can assume the file is open.
     29                    * VERY IMPORTANT: use "b" option to fopen() if you are on a machine that
     30                    * requires it in order to read binary files.
     31                    */
     32     if ((infile = fopen(strImageName.c_str(), "rb")) == NULL) {
     33         fprintf(stderr, "can't open %s
    ", strImageName);
     34         return -1;
     35     }
     36 
     37     /* Step 1: allocate and initialize JPEG decompression object */
     38     /* We set up the normal JPEG error routines, then override error_exit. */
     39     cinfo.err = jpeg_std_error(&jerr);
     40     /* Establish the setjmp return context for my_error_exit to use. */
     41     //if (setjmp(jerr.setjmp_buffer)) {  
     42     /* If we get here, the JPEG code has signaled an error.
     43     * We need to clean up the JPEG object, close the input file, and return.
     44     */
     45     //jpeg_destroy_decompress(&cinfo);  
     46     //fclose(infile);  
     47     //return -1;  
     48     //}  
     49 
     50     /* Now we can initialize the JPEG decompression object. */
     51     jpeg_create_decompress(&cinfo);
     52 
     53     /* Step 2: specify data source (eg, a file) */
     54     jpeg_stdio_src(&cinfo, infile);
     55 
     56     /* Step 3: read file parameters with jpeg_read_header() */
     57     jpeg_read_header(&cinfo, TRUE);
     58     /* We can ignore the return value from jpeg_read_header since
     59     *   (a) suspension is not possible with the stdio data source, and
     60     *   (b) we passed TRUE to reject a tables-only JPEG file as an error.
     61     * See libjpeg.txt for more info.
     62     */
     63     printf("image_width = %d
    ", cinfo.image_width);
     64     printf("image_height = %d
    ", cinfo.image_height);
     65     printf("num_components = %d
    ", cinfo.num_components);
     66 
     67     /* Step 4: set parameters for decompression */
     68     /* In this example, we don't need to change any of the defaults set by
     69     * jpeg_read_header(), so we do nothing here.
     70     */
     71     printf("enter scale M/N:
    ");
     72     //scanf("%d/%d", &cinfo.scale_num, &cinfo.scale_denom);  
     73     cinfo.scale_num = 1;
     74     cinfo.scale_denom = 1;
     75     printf("scale to : %d/%d
    ", cinfo.scale_num, cinfo.scale_denom);
     76 
     77     /* Step 5: Start decompressor */
     78     jpeg_start_decompress(&cinfo);
     79     /* We can ignore the return value since suspension is not possible
     80     * with the stdio data source.
     81     */
     82 
     83     //输出的图象的信息  
     84     printf("output_width = %d
    ", cinfo.output_width);
     85     printf("output_height = %d
    ", cinfo.output_height);
     86     printf("output_components = %d
    ", cinfo.output_components);
     87 
     88     /* We may need to do some setup of our own at this point before reading
     89     * the data.  After jpeg_start_decompress() we have the correct scaled
     90     * output image dimensions available, as well as the output colormap
     91     * if we asked for color quantization.
     92     * In this example, we need to make an output work buffer of the right size.
     93     */
     94     /* JSAMPLEs per row in output buffer */
     95     row_stride = cinfo.output_width * cinfo.output_components;
     96     /* Make a one-row-high sample array that will go away when done with image */
     97     buffer = (*cinfo.mem->alloc_sarray)((j_common_ptr)&cinfo, JPOOL_IMAGE, row_stride, 1);
     98 
     99     /* Step 6: while (scan lines remain to be read) */
    100     /*           jpeg_read_scanlines(...); */
    101     /* Here we use the library's state variable cinfo.output_scanline as the
    102     * loop counter, so that we don't have to keep track ourselves.
    103     */
    104     while (cinfo.output_scanline < cinfo.output_height) {
    105         /* jpeg_read_scanlines expects an array of pointers to scanlines.
    106         * Here the array is only one element long, but you could ask for
    107         * more than one scanline at a time if that's more convenient.
    108         */
    109         jpeg_read_scanlines(&cinfo, buffer, 1);
    110         /* Assume put_scanline_someplace wants a pointer and sample count. */
    111         //put_scanline_someplace(buffer[0], row_stride);  
    112     }
    113 
    114     /* Step 7: Finish decompression */
    115     jpeg_finish_decompress(&cinfo);
    116     /* We can ignore the return value since suspension is not possible
    117     * with the stdio data source.
    118     */
    119 
    120     /* Step 8: Release JPEG decompression object */
    121     /* This is an important step since it will release a good deal of memory. */
    122     jpeg_destroy_decompress(&cinfo);
    123 
    124     /* After finish_decompress, we can close the input file.
    125     * Here we postpone it until after no more JPEG errors are possible,
    126     * so as to simplify the setjmp error logic above.  (Actually, I don't
    127     * think that jpeg_destroy can do an error exit, but why assume anything...)
    128     */
    129     fclose(infile);
    130 
    131     /* At this point you may want to check to see whether any corrupt-data
    132     * warnings occurred (test whether jerr.pub.num_warnings is nonzero).
    133     */
    134 
    135     return 0;
    136 }
    137 
    138 int write_JPEG_file(string strImageName, int quality)
    139 {
    140     unsigned char* image_buffer;    /* Points to large array of R,G,B-order data */
    141     int image_height = 780; /* Number of rows in image */
    142     int image_width = 1040;  /* Number of columns in image */
    143 
    144                             /* This struct contains the JPEG compression parameters and pointers to
    145                             * working space (which is allocated as needed by the JPEG library).
    146                             * It is possible to have several such structures, representing multiple
    147                             * compression/decompression processes, in existence at once.  We refer
    148                             * to any one struct (and its associated working data) as a "JPEG object".
    149                             */
    150     struct jpeg_compress_struct cinfo;
    151 
    152     /* This struct represents a JPEG error handler.  It is declared separately
    153     * because applications often want to supply a specialized error handler
    154     * (see the second half of this file for an example).  But here we just
    155     * take the easy way out and use the standard error handler, which will
    156     * print a message on stderr and call exit() if compression fails.
    157     * Note that this struct must live as long as the main JPEG parameter
    158     * struct, to avoid dangling-pointer problems.
    159     */
    160     struct jpeg_error_mgr jerr;
    161     /* More stuff */
    162     FILE * outfile;     /* target file */
    163     JSAMPROW row_pointer[1];    /* pointer to JSAMPLE row[s] */
    164     int row_stride;     /* physical row width in image buffer */
    165 
    166                         /* Step 1: allocate and initialize JPEG compression object */
    167 
    168                         /* We have to set up the error handler first, in case the initialization
    169                         * step fails.  (Unlikely, but it could happen if you are out of memory.)
    170                         * This routine fills in the contents of struct jerr, and returns jerr's
    171                         * address which we place into the link field in cinfo.
    172                         */
    173     cinfo.err = jpeg_std_error(&jerr);
    174     /* Now we can initialize the JPEG compression object. */
    175     jpeg_create_compress(&cinfo);
    176 
    177     /* Step 2: specify data destination (eg, a file) */
    178     /* Note: steps 2 and 3 can be done in either order. */
    179 
    180     /* Here we use the library-supplied code to send compressed data to a
    181     * stdio stream.  You can also write your own code to do something else.
    182     * VERY IMPORTANT: use "b" option to fopen() if you are on a machine that
    183     * requires it in order to write binary files.
    184     */
    185     if ((outfile = fopen(strImageName.c_str(), "wb")) == NULL) {
    186         fprintf(stderr, "can't open %s
    ", strImageName);
    187         //exit(1);  
    188         return -1;
    189     }
    190     jpeg_stdio_dest(&cinfo, outfile);
    191 
    192     /* Step 3: set parameters for compression */
    193     /* First we supply a description of the input image.
    194     * Four fields of the cinfo struct must be filled in:
    195     */
    196     cinfo.image_width = image_width;    /* image width and height, in pixels */
    197     cinfo.image_height = image_height;
    198     cinfo.input_components = 3;     /* # of color components per pixel */
    199     cinfo.in_color_space = JCS_RGB;     /* colorspace of input image */
    200                                         /* Now use the library's routine to set default compression parameters.
    201                                         * (You must set at least cinfo.in_color_space before calling this,
    202                                         * since the defaults depend on the source color space.)
    203                                         */
    204     jpeg_set_defaults(&cinfo);
    205     /* Now you can set any non-default parameters you wish to.
    206     * Here we just illustrate the use of quality (quantization table) scaling:
    207     */
    208     jpeg_set_quality(&cinfo, quality, TRUE /* limit to baseline-JPEG values */);
    209 
    210     /* Step 4: Start compressor */
    211     /* TRUE ensures that we will write a complete interchange-JPEG file.
    212     * Pass TRUE unless you are very sure of what you're doing.
    213     */
    214     jpeg_start_compress(&cinfo, TRUE);
    215 
    216     /* Step 5: while (scan lines remain to be written) */
    217     /*           jpeg_write_scanlines(...); */
    218     /* Here we use the library's state variable cinfo.next_scanline as the
    219     * loop counter, so that we don't have to keep track ourselves.
    220     * To keep things simple, we pass one scanline per call; you can pass
    221     * more if you wish, though.
    222     */
    223     row_stride = image_width * 3;   /* JSAMPLEs per row in image_buffer */
    224 
    225     image_buffer = new unsigned char[row_stride * cinfo.image_height];
    226     memset(image_buffer, 0xff, row_stride * cinfo.image_height);
    227 
    228     int line = 0;
    229     //while (cinfo.next_scanline < cinfo.image_height) {  
    230     while (line < cinfo.image_height) {
    231         /* jpeg_write_scanlines expects an array of pointers to scanlines.
    232         * Here the array is only one element long, but you could pass
    233         * more than one scanline at a time if that's more convenient.
    234         */
    235         //row_pointer[0] = &image_buffer[cinfo.next_scanline * row_stride];  
    236         row_pointer[0] = &image_buffer[line * row_stride];
    237         jpeg_write_scanlines(&cinfo, row_pointer, 1);
    238 
    239         line++;
    240     }
    241 
    242     delete image_buffer;
    243 
    244     /* Step 6: Finish compression */
    245     jpeg_finish_compress(&cinfo);
    246     /* After finish_compress, we can close the output file. */
    247     fclose(outfile);
    248 
    249     /* Step 7: release JPEG compression object */
    250     /* This is an important step since it will release a good deal of memory. */
    251     jpeg_destroy_compress(&cinfo);
    252 
    253     return 0;
    254 }
    255 
    256 struct Image
    257 {
    258     int bpp;
    259     int width;
    260     int height;
    261     unsigned char* data;
    262 };
    263 
    264 struct jerror_mgr
    265 {
    266     jpeg_error_mgr base;
    267     jmp_buf        jmp;
    268 };
    269 
    270 METHODDEF(void) jerror_exit(j_common_ptr jinfo)
    271 {
    272     jerror_mgr* err = (jerror_mgr*)jinfo->err;
    273     longjmp(err->jmp, 1);
    274 }
    275 
    276 METHODDEF(void) joutput_message(j_common_ptr)
    277 {
    278 }
    279 
    280 bool Image_LoadJpeg(Image* image, unsigned char* img_data, unsigned int img_size)
    281 {
    282     jpeg_decompress_struct jinfo;
    283     jerror_mgr jerr;
    284 
    285     jinfo.err = jpeg_std_error(&jerr.base);
    286     jerr.base.error_exit = jerror_exit;
    287     jerr.base.output_message = joutput_message;
    288     jpeg_create_decompress(&jinfo);
    289 
    290     image->data = NULL;
    291 
    292     if (setjmp(jerr.jmp)) goto bail;
    293 
    294     jpeg_mem_src(&jinfo, img_data, img_size);
    295 
    296     if (jpeg_read_header(&jinfo, TRUE) != JPEG_HEADER_OK) goto bail;
    297 
    298     jinfo.dct_method = JDCT_FLOAT; // change this to JDCT_ISLOW on Android/iOS  
    299 
    300     if (!jpeg_start_decompress(&jinfo)) goto bail;
    301 
    302     if (jinfo.num_components != 1 && jinfo.num_components != 3) goto bail;
    303 
    304     image->data = new (std::nothrow) unsigned char[jinfo.output_width * jinfo.output_height * jinfo.output_components];
    305     if (!image->data) goto bail;
    306 
    307     {
    308         JSAMPROW ptr = image->data;
    309         while (jinfo.output_scanline < jinfo.output_height)
    310         {
    311             if (jpeg_read_scanlines(&jinfo, &ptr, 1) != 1) goto bail;
    312 
    313             ptr += jinfo.output_width * jinfo.output_components;
    314         }
    315     }
    316 
    317     if (!jpeg_finish_decompress(&jinfo)) goto bail;
    318 
    319     image->bpp = jinfo.output_components;
    320     image->width = jinfo.output_width;
    321     image->height = jinfo.output_height;
    322 
    323     jpeg_destroy_decompress(&jinfo);
    324 
    325     return true;
    326 
    327 bail:
    328     jpeg_destroy_decompress(&jinfo);
    329     if (image->data) delete[] image->data;
    330 
    331     return false;
    332 }
    333 
    334 struct ImageData {
    335     unsigned char *pixels;
    336     long  width;
    337     long height;
    338 };
    339 
    340 int TestImage(string strSrcImageName, string strDstImageName)
    341 {
    342     //read  
    343     struct jpeg_decompress_struct cinfo_decompress;
    344     FILE* infile;
    345     int row_stride;
    346     struct jpeg_error_mgr jerr;
    347 
    348     if ((infile = fopen(strSrcImageName.c_str(), "rb")) == NULL) {
    349         fprintf(stderr, "can't open %s
    ", strSrcImageName);
    350         return -1;
    351     }
    352 
    353     cinfo_decompress.err = jpeg_std_error(&jerr);
    354     jpeg_create_decompress(&cinfo_decompress);
    355     jpeg_stdio_src(&cinfo_decompress, infile);
    356     int ret = jpeg_read_header(&cinfo_decompress, TRUE);
    357     if (ret != JPEG_HEADER_OK) return -1;
    358     jpeg_start_decompress(&cinfo_decompress);
    359     row_stride = cinfo_decompress.output_width * cinfo_decompress.output_components;
    360     int buffer_height = 1;
    361     JSAMPARRAY buffer = (JSAMPARRAY)malloc(sizeof(JSAMPROW) * buffer_height);
    362     buffer[0] = (JSAMPROW)malloc(sizeof(JSAMPLE) * row_stride);
    363     //JSAMPARRAY buffer = (*cinfo_decompress.mem->alloc_sarray)((j_common_ptr)&cinfo_decompress, JPOOL_IMAGE, row_stride, 1);  
    364     ImageData *imageData;
    365     imageData = new ImageData;
    366     imageData->width = cinfo_decompress.output_width;
    367     imageData->height = cinfo_decompress.output_height;
    368 
    369     imageData->pixels = new unsigned char[cinfo_decompress.output_width * cinfo_decompress.output_height * cinfo_decompress.output_components];
    370     long counter = 0;
    371 
    372     while (cinfo_decompress.output_scanline < cinfo_decompress.output_height) {
    373         jpeg_read_scanlines(&cinfo_decompress, buffer, 1);
    374         memcpy(imageData->pixels + counter, buffer[0], row_stride);
    375         counter += row_stride;
    376     }
    377 
    378     jpeg_finish_decompress(&cinfo_decompress);
    379     jpeg_destroy_decompress(&cinfo_decompress);
    380 
    381     fclose(infile);
    382 
    383     //write  
    384     unsigned char* image_buffer;
    385     int image_height = cinfo_decompress.output_height;
    386     int image_width = cinfo_decompress.output_width;
    387     FILE * outfile;
    388     JSAMPROW row_pointer[1];
    389     int row_stride_dst;
    390     struct jpeg_compress_struct cinfo_compress;
    391     cinfo_compress.err = jpeg_std_error(&jerr);
    392     jpeg_create_compress(&cinfo_compress);
    393 
    394     if ((outfile = fopen(strDstImageName.c_str(), "wb")) == NULL) {
    395         fprintf(stderr, "can't open %s
    ", strDstImageName);
    396         //exit(1);  
    397         return -1;
    398     }
    399 
    400     jpeg_stdio_dest(&cinfo_compress, outfile);
    401 
    402     cinfo_compress.image_width = image_width;
    403     cinfo_compress.image_height = image_height;
    404     cinfo_compress.input_components = 3;
    405     cinfo_compress.in_color_space = JCS_EXT_RGB;
    406 
    407     int quality = 70;
    408     jpeg_set_defaults(&cinfo_compress);
    409     jpeg_set_quality(&cinfo_compress, quality, TRUE);
    410     jpeg_start_compress(&cinfo_compress, TRUE);
    411 
    412     row_stride_dst = image_width * 3;
    413 
    414     image_buffer = new unsigned char[row_stride_dst * cinfo_compress.image_height];
    415     memcpy(image_buffer, imageData->pixels, row_stride_dst * cinfo_compress.image_height);
    416 
    417     while (cinfo_compress.next_scanline < cinfo_compress.image_height) {
    418         row_pointer[0] = &image_buffer[cinfo_compress.next_scanline * row_stride_dst];
    419         jpeg_write_scanlines(&cinfo_compress, row_pointer, 1);
    420     }
    421 
    422     jpeg_finish_compress(&cinfo_compress);
    423     fclose(outfile);
    424     jpeg_destroy_compress(&cinfo_compress);
    425 
    426     if (imageData) {
    427         delete imageData;
    428         imageData = NULL;
    429     }
    430 
    431     if (image_buffer)
    432         delete[] image_buffer;
    433 
    434     return 0;
    435 }
    436 
    437 int main(int argc, char* argv[])
    438 {
    439     string strImageName = "data/srcImg/moon.jpg";
    440     int flag1 = read_JPEG_file(strImageName);
    441     if (flag1 == 0) cout << "read ok!" << endl;
    442     else cout << "read error!" << endl;
    443 
    444     strImageName = "2.bmp";
    445     int flag2 = write_JPEG_file(strImageName, 80);
    446     if (flag2 == 0) cout << "write ok!" << endl;
    447     else cout << "write error!" << endl;
    448 
    449     string strSrcImageName = "data/srcImg/moon.jpg";
    450     string strDstImageName = "b.jpg";
    451     int flag3 = TestImage(strSrcImageName, strDstImageName);
    452     if (flag3 == 0) cout << "test ok!" << endl;
    453     else cout << "test error!" << endl;
    454 
    455     return 0;
    456 }
    View Code
  • 相关阅读:
    Django与forms组件校验源码
    局部钩子和和全局钩子
    Form组件参数配置
    Form渲染错误信息
    Django与分页器
    Django与from组件
    uiautomatorview 提示:no android devies were detected by adb
    Flutter 应用入门:包管理
    Flutter 应用入门:路由管理
    Flutter 应用入门:计数器
  • 原文地址:https://www.cnblogs.com/riddick/p/7767435.html
Copyright © 2011-2022 走看看