One of image decoding-using libjpeg to decode JPEG images

Source: Internet
Author: User
Document directory
  • Libjpeg Introduction
  • Use of libjpeg Library
  • Summary

Multimedia Applications are becoming more and more important in today's electronic products, especially in embedded devices. This series of articles will introduce how to use libjpeg to decode JPEG files, libpng to decode PNG files, and libgif to decode GIF files. This article describes how to use libjpeg to decode JPEG files.

Libjpeg Introduction

Libjpeg is a library fully written in C language. It includes the widely used JPEG decoding, JPEG encoding, and other JPEG functions. This library is maintained by an independent JPEG Working Group. The latest version is 6B, which was released on July 6, 1998. For details, refer to the introduction to libjpeg in Wikipedia.

Libjpeg Database Data Structure

When JPEG data is decoded using the libjpeg library, the most important data type is struct.
Jpeg_decompress_struct. A common variable is defined as a Cinfo variable. This variable stores the details of JPEG data and the output data details after decoding.
. Generally, this variable needs to be passed in as the first parameter every time you call the libjpeg library API. In addition, you can modify this variable to modify the libjpeg behavior.
For example, the output data format and the maximum memory available for the libjpeg library.

Use of the libjpeg Library 1. Set error handling functions


If we use the libjpeg library, errors are inevitable. Therefore, before using libjpeg decoding, we must handle errors first. In the libjpeg library,
The default error handling function is implemented. When an error occurs, for example, if the memory is insufficient (which is very likely to happen, we will introduce it later, the default error handler function calls the exit function to end the entire process.
For more information, see the jerror. c file. This is not suitable for many users, but libjpeg provides an interface for us to register a custom error handler.

C language does not support the C ++ Exception Handling Mechanism, but provides the setjmp and longjmp mechanisms to implement similar functions. If you are not familiar with this mechanism, please refer to the C language manual. The code snippets below in this article are all from the libjpeg example. c file. You can refer to them.

   1: /* We set up the normal JPEG error routines, then override error_exit. */
   2: cinfo.err = jpeg_std_error(&jerr.pub);
   3: jerr.pub.error_exit = my_error_exit;
   4: /* Establish the setjmp return context for my_error_exit to use. */
   5: if (setjmp(jerr.setjmp_buffer)) {
   6:   /* If we get here, the JPEG code has signaled an error.
   7:    * We need to clean up the JPEG object, close the input file, and return.
   8:    */
   9:   jpeg_destroy_decompress(&cinfo);
  10:   fclose(infile);
  11:   return 0;
  12: }


The focus of the above Code is that we have registered a my_error_exit callback function with libjpeg. When an error occurs, the callback function will be called. Then we call
Setjmp function, set a return point. In this way, after the my_error_exit callback function finishes processing the error message, you can call the longjmp function to return it here.
The return point is used to release resources (it is very important, otherwise the memory will leak ). Let's take a look at the implementation of the my_error_exit callback function:

   1: /*
   2:  * Here's the routine that will replace the standard error_exit method:
   3:  */
   4: METHODDEF(void)
   5: my_error_exit (j_common_ptr cinfo)
   6: {
   7:   /* cinfo->err really points to a my_error_mgr struct, so coerce pointer */
   8:   my_error_ptr myerr = (my_error_ptr) cinfo->err;
   9:  
  10:   /* Always display the message. */
  11:   /* We could postpone this until after returning, if we chose. */
  12:   (*cinfo->err->output_message) (cinfo);
  13:  
  14:   /* Return control to the setjmp point */
  15:   longjmp(myerr->setjmp_buffer, 1);
  16: }

You can check the value of Cinfo-> err-> msg_code to determine the error type and handle it accordingly. In this example, only an error message is printed. Finally, call longjmp to jump to the place where setjmp is called.

2. initialize the decoded object

This step is required to use libjpeg to decode JPEG data.

   1: /* Now we can initialize the JPEG decompression object. */
   2: jpeg_create_decompress(&cinfo);

After this step, if decoding is completed or an error occurs, you need to call pai_destroy_decompress to destroy the decoded object. Otherwise, the memory will leak.

3. initialize source data

The libjpeg Library only provides an interface for using files as input data. The code in example. C is as follows:

   1: /* Step 2: specify data source (eg, a file) */
   2: jpeg_stdio_src(&cinfo, infile);


I personally think this design is very unreasonable. I think a friendly library needs to be able to accept all kinds of input (memory data, network data, etc ). A friendly way is to provide several common input data support
Hold (such as file input in libjpeg ). Then, you need to provide an interface for users to register custom Input Functions (callback functions), so that the Library can adapt to a variety of input data classes in real life.
Type. Simon also wrote in his previous blog post how to modify the libjpeg library so that it can decode JPEG data in the memory buffer. For details, refer to libjpeg decoding JPEG data in memory. Of course, Simon does not extend the libjpeg library to allow users to register custom Input Functions (callback functions). If you are interested, you can implement it on your own.

4. Read the header information of the JPEG file

This is the same as initializing the decoded object. It must be called and agreed.

   1: /* Step 3: read file parameters with jpeg_read_header() */
   2: (void) jpeg_read_header(&cinfo, TRUE);
5. Set decoding Parameters

In many cases, this step is very important. For example, you can set the output format, scale, and so on. Set parameters by modifying the value of Cinfo in the previous step. Here we will briefly introduce some common fields.

Out_color_space: The output color format. libjpeg is defined as follows:

   1: /* Known color spaces. */
   2: typedef enum {
   3:     JCS_UNKNOWN,        /* error/unspecified */
   4:     JCS_GRAYSCALE,        /* monochrome */
   5:     JCS_RGB,        /* red/green/blue */
   6:     JCS_YCbCr,        /* Y/Cb/Cr (also known as YUV) */
   7:     JCS_CMYK,        /* C/M/Y/K */
   8:     JCS_YCCK,        /* Y/Cb/Cr/K */
   9: #ifdef ANDROID_RGB
  10:     JCS_RGBA_8888,  /* red/green/blue/alpha */
  11:     JCS_RGB_565     /* red/green/blue in 565 format */
  12: #endif
  13: } J_COLOR_SPACE;

We can see that Google has extended several output formats in Android, so if you need the color format output format libjpeg not supported (compared
For example, yuyv and other color formats), please refer to Android's libjpeg extensions for self-modification without worrying about complexity and easy implementation. Please study
The jinit_color_deconverter function in the jdcolor. c file.

Scale_num, scale_denom: Because the actual display device is ever-changing, we may need to scale the output data to display it. Libjpeg supports scaling the output data. This variable is used to set the scaling parameter. Currently, libjpeg supports 1/2, 1/4, and 1/8 scaling.

Mem: You can specify the content related to memory management, such as allocating and releasing memory and specifying libjpeg
Maximum memory that can be used. By default, each platform has a libjpeg default maximum available memory value. For example, the value above the Android platform is
Memory 000l (10 m). See default_max_mem in jmemxxxx. C to learn the default maximum memory values of different platforms. By modifying
Mem-> pub. max_memory_to_use value. The library user can customize the maximum memory value that libjpeg can use.

6. Start Decoding

After the preceding parameter settings, we can start decoding. There is nothing to say.

   1: /* Step 5: Start decompressor */
   2: (void) jpeg_start_decompress(&cinfo);
7. Read and decode data
   1: /* Here we use the library's state variable cinfo.output_scanline as the
   2:  * loop counter, so that we don't have to keep track ourselves.
   3:  */
   4: while (cinfo.output_scanline < cinfo.output_height) {
   5:   /* jpeg_read_scanlines expects an array of pointers to scanlines.
   6:    * Here the array is only one element long, but you could ask for
   7:    * more than one scanline at a time if that's more convenient.
   8:    */
   9:   (void) jpeg_read_scanlines(&cinfo, buffer, 1);
  10:   /* Assume put_scanline_someplace wants a pointer and sample count. */
  11:   put_scanline_someplace(buffer[0], row_stride);
  12: }

Note that although the jpeg_read_scanlines function can specify the number of rows to be read at a time, the function currently supports only one read-only row at a time.

8. End Decoding
   1: /* Step 7: Finish decompression */
   2: (void) jpeg_finish_decompress(&cinfo);
9. Release the decoded object
   1: /* Step 8: Release JPEG decompression object */
   2:  
   3: /* This is an important step since it will release a good deal of memory. */
   4: jpeg_destroy_decompress(&cinfo);

At this point, a JPEG data has been parsed. Although there are many steps, it is relatively simple for conventional use.

Summary


Libjpeg can better decode baseline JPEG data, but it requires a lot of memory when decoding progressive JPEG data (I tested
Progressive images have been found to consume 70 MB of memory ). If your hardware can decode JPEG data, use hardware to decode JPEG data as much as possible.

Original

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.