Jpeglib libray

From NoskeWiki
Jump to navigation Jump to 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