Jpeglib libray

From NoskeWiki
Jump to: navigation, search

About

libjpeg or jpeglib (it's confusing but it seems to get referred to as both, and the include is "jpeglib.h") is a small library written entirely in C which contains a widely-used implementation of a JPEG decoder, JPEG encoder and other JPEG utilities. This library is maintained by the Independent JPEG Group and represents a very popular library which is often incorporated into other libraries, so in many cases you may use libjpeg as part of something else without realizing it. Here I describe how you can use libjpeg in a minimal example of creating a JPEG file.

Installing libjpeg

  • #1) Download libjpeg from this directory: http://www.ijg.org/files/
    NOTE: The .tar.gz versions are for Unix and .zip for Windows... I used "jpegsrc.v6b.tar.gz" on my OS X machine.
  • #2) Unzip or gzip with this command (or use a program):
tar zxvf jpegsrc.v6b.tar.gz
  • #3) Install with these two commands:
./configure --prefix=/usr --enable-static --enable-shared && make
sudo make install

On Linux/Mac OSX this should install to: /usr/local/lib/libjpeg.a


Example: Using jpeglib to generate and write out a jpeg image

Here I've written an example of how you can use the jpeglib to save a jpeg image to file.

Create a file called write_jpeg_example.cpp with this content:

/*
 *  File:       write_jpeg_example.cpp
 *  By:         Andrew Noske
 *  About:
 *          This file deomstrated the use of "jpeglib"
 *          by generating a small test image of a checkerboard
 *          with red and white pixels and the writes this
 *          out to a jpeg file called "test_jpeg.jpg".
 */
 
#include <stdlib.h>
#include <stdio.h>
#include <jpeglib.h>
 
//-----------------------------
 
int main(int argc, char *argv[])
{
  char *filename = (char *)"test_jpeg.jpg";
  int quality    = 50;
 
  struct jpeg_compress_struct cinfo;    // Basic info for JPEG properties.
  struct jpeg_error_mgr jerr;           // In case of error.
  FILE * outfile;                       // Target file.
  JSAMPROW row_pointer[1];              // Pointer to JSAMPLE row[s].
  int row_stride;                       // Physical row width in image buffer.
 
  //## ALLOCATE AND INITIALIZE JPEG COMPRESSION OBJECT
 
  cinfo.err = jpeg_std_error(&jerr);
  jpeg_create_compress(&cinfo);
 
  //## OPEN FILE FOR DATA DESTINATION:
 
  if ((outfile = fopen(filename, "wb")) == NULL) {
    fprintf(stderr, "ERROR: can't open %s\n", filename);
    exit(1);
  }
  jpeg_stdio_dest(&cinfo, outfile);
 
  //## SET PARAMETERS FOR COMPRESSION:
 
  cinfo.image_width  = 20;           // |-- Image width and height in pixels.
  cinfo.image_height = 20;           // |
  cinfo.input_components = 3;         // Number of color components per pixel.
  cinfo.in_color_space = JCS_RGB;     // Colorspace of input image as RGB.
 
  jpeg_set_defaults(&cinfo);
  jpeg_set_quality(&cinfo, quality, TRUE);
 
 
  //## CREATE IMAGE BUFFER TO WRITE FROM AND MODIFY THE IMAGE TO LOOK LIKE CHECKERBOARD:
 
  unsigned char *image_buffer = NULL;
  image_buffer = (unsigned char*)malloc(cinfo.image_width*cinfo.image_height*cinfo.num_components);
 
  for(int y=0;y<cinfo.image_height; y++)
  for(int x=0;x<cinfo.image_width; x++)
  {
    unsigned int pixelIdx = ((y*cinfo.image_height)+x) * cinfo.input_components; 
 
    if(x%2==y%2)
    {
      image_buffer[pixelIdx+0] = 255;   // r |-- Set r,g,b components to
      image_buffer[pixelIdx+1] = 0;     // g |   make this pixel red
      image_buffer[pixelIdx+2] = 0;     // b |   (255,0,0).
    }
    else
    {
      image_buffer[pixelIdx+0] = 255;   // r |-- Set r,g,b components to
      image_buffer[pixelIdx+1] = 255;   // g |   make this pixel white
      image_buffer[pixelIdx+2] = 255;   // b |   (255,255,255).
    }
  }
 
  //## START COMPRESSION:
 
  jpeg_start_compress(&cinfo, TRUE);
  row_stride = cinfo.image_width * 3;        // JSAMPLEs per row in image_buffer
 
  while (cinfo.next_scanline < cinfo.image_height)
  {
    row_pointer[0] = &image_buffer[cinfo.next_scanline * row_stride];
    (void) jpeg_write_scanlines(&cinfo, row_pointer, 1);
  }
            // NOTE: jpeg_write_scanlines expects an array of pointers to scanlines.
            //       Here the array is only one element long, but you could pass
            //       more than one scanline at a time if that's more convenient.
 
  //## FINISH COMPRESSION AND CLOSE FILE:
 
  jpeg_finish_compress(&cinfo);
  fclose(outfile);
  jpeg_destroy_compress(&cinfo);
 
  printf("SUCCESS\n");  
 
  exit(0);
}

To compile this code change to the correct directory then enter:

g++ -o write_jpeg_example write_jpeg_example.cpp -lz /usr/local/lib/libjpeg.a
./write_jpeg_example

The second line of code should run the program and you should see "test_jpeg.jpg" appear in the same directory.


Acknowledgements: This code has been simplified and modified from this code on jpegcameras.com



Links