Jpgread

From RoutineWiki

Jump to: navigation, search

Contents

Credits and License details

The code of this routine is a improved version of the code from http://wiki.octave.org.

Author(s)

Maintainer(s)

The software provided in this page is maintained by:

Disclaimer

No warranty of any kind is implied for the uses of the source code provided in this page. It is provided 'as is'. Use at your own risk.

License

Released under the GNU Free Documentation License.

Other licenses

There are no other licenses.

Instalation

  • Copy the code from the section Code and save it in a file named ~/jpgread.cc
  • Create a .oct file using the command:
mkoctfile ~/jpgread.cc -ljpeg

This command will create the file jpgread.oct in the same folder

  • Move the jpgread.oct to the octave oct-site folder.

If you don't know where to place the .oct file, use the command

octave-config --oct-site-dir

that will show to you the appropriate place to move the .oct file.

  • Delete the jpgread.cc

If you dont want to store the jpgread.cc for future installs, you can now safety remove it.

Code

// FILE: jpgread.cc

 #include <octave/oct.h>
 
 extern "C" {
   #include "jpeglib.h"
 } //extern "C"
 
 DEFUN_DLD (jpgread, args, nargout ,
 "JPGREAD Read a JPEG file from disk. \n\
   X = jpgread('filename') reads the specified file\n")
 { 
    octave_value_list retval;
    int nargin  = args.length();
 
    JSAMPARRAY buffer;
    long row_stride;
    struct jpeg_decompress_struct cinfo;
    struct jpeg_error_mgr jerr;
 
    if (nargin != 1 || !args(0).is_string() ) {
       print_usage ("jpgread");
       return retval;
    }
 
    std::string filename = args(0).string_value();
    FILE * infile = fopen(filename.c_str(), "rb");
 
    if (infile == NULL) {
       error("Couldn't open file");
       return retval;
    }
 
    cinfo.err = jpeg_std_error(&jerr);

    jpeg_create_decompress(&cinfo); 

    jpeg_stdio_src(&cinfo, infile);
    jpeg_read_header(&cinfo, TRUE);
    switch(nargout)
    {
        case 0:
            return retval;
        case 1:
            cinfo.out_color_space = JCS_GRAYSCALE;
            cinfo.quantize_colors = FALSE;
            cinfo.dct_method = JDCT_FLOAT;
            cinfo.out_color_components = 256;
            cinfo.output_components = 1;
            jpeg_calc_output_dimensions(&cinfo);
            row_stride = cinfo.output_width ;
            buffer = (*cinfo.mem->alloc_sarray)
                  ((j_common_ptr) &cinfo, JPOOL_IMAGE, cinfo.output_width, cinfo.rec_outbuf_height);
            jpeg_start_decompress(&cinfo);
            break;
        case 3:
            cinfo.out_color_space = JCS_RGB;
            cinfo.quantize_colors = FALSE;
            cinfo.dct_method = JDCT_FLOAT;
            jpeg_calc_output_dimensions(&cinfo);
            row_stride = cinfo.output_width * cinfo.output_components;
            buffer = (*cinfo.mem->alloc_sarray)
                ((j_common_ptr) &cinfo, JPOOL_IMAGE, row_stride, cinfo.rec_outbuf_height);
            jpeg_start_decompress(&cinfo);
            break;
        }
        cinfo.mem->max_memory_to_use = 10000000L;
        switch(nargout)
        {
            case 1:
            {
                Matrix avg   ( cinfo.output_height ,  cinfo.output_width );
                unsigned long num_scanlines,j=0,k=0;
                while (cinfo.output_scanline < cinfo.output_height) 
                {
                    num_scanlines = jpeg_read_scanlines(&cinfo, buffer,
                         cinfo.rec_outbuf_height);
                    k = 0;
                    while(k<num_scanlines)
                    {
                        for (unsigned long i=0; i<cinfo.output_width; i++) {
                            avg(j,i)   = buffer[k][i];
                        }
                        j++;
                        k++;
                    }
                }
                retval(0)= avg;
                break;
            }
            case 3:
            {
                Matrix r( cinfo.output_height ,  cinfo.output_width );
                Matrix g( cinfo.output_height ,  cinfo.output_width );
                Matrix b( cinfo.output_height ,  cinfo.output_width );
                unsigned long k = 0;
                for (unsigned long j=0; j  < cinfo.output_height; j+=k) 
                {
                    k=(cinfo.rec_outbuf_height+j<cinfo.output_height)?cinfo.rec_outbuf_height:cinfo.output_height-j;
                    k=jpeg_read_scanlines(&cinfo, buffer,k);
                    for(unsigned long s=0;s<k && s+j<cinfo.output_height;s++)
                    {
                        for (unsigned long i=0; i<cinfo.output_width; i++) {
                            r(j+s,i)   = buffer[s][i*cinfo.output_components];
                            g(j+s,i)   = buffer[s][i*cinfo.output_components+1];
                            b(j+s,i)   = buffer[s][i*cinfo.output_components+2];
                    }
                } // for i
            } //for j
            retval(0)=r;
            retval(1)=g;
            retval(2)=b;
        }
    }
    jpeg_finish_decompress(&cinfo);
    jpeg_destroy_decompress(&cinfo);
    fclose(infile);
    return retval;
};

Usage

Octave needs to be restarted after install the new jpgread.oct file. After that, you can issue the command :

[r,g,b] = jpgread('~/myimage.jpg')

for reading color information on your image file. The command will return the three 2-dimensional matrixes corresponding to the colour components. If you want to work in grayscale, you can use instead :

img = jpgread('~/myimage.jpg')

that will return a single 2-dimensional matrix with the grayscale levels.

see also

Personal tools