qjpeg/JPEGFile.cpp
changeset 76 9cbf4c7e7986
child 78 a55bf2fa3f74
equal deleted inserted replaced
75:327eef3fe747 76:9cbf4c7e7986
       
     1 #include <cstring>
       
     2 #include <cstdio>
       
     3 
       
     4 extern "C"
       
     5 {
       
     6 #include <stdio.h>
       
     7 #include <jpeglib.h>
       
     8 }
       
     9 
       
    10 #include "FloatPlane.h"
       
    11 #include "Image.h"
       
    12 #include "JPEGFile.h"
       
    13 
       
    14 JPEGFile::JPEGFile(const char *_filename)
       
    15 {
       
    16     using namespace std;
       
    17     filename = new char[std::strlen(_filename) + 1];
       
    18     std::strcpy(filename, _filename);
       
    19     srcinfo = new jpeg_decompress_struct;
       
    20     jsrcerr = new jpeg_error_mgr;
       
    21 }
       
    22 
       
    23 void JPEGFile::readHeader()
       
    24 {
       
    25     srcinfo->err = jpeg_std_error(jsrcerr);
       
    26 
       
    27     jpeg_create_decompress(srcinfo);
       
    28 
       
    29     inputh = fopen(filename, "rb");
       
    30 
       
    31     jpeg_stdio_src(srcinfo, inputh);
       
    32     jpeg_read_header(srcinfo, TRUE);
       
    33 }
       
    34 
       
    35 Image *JPEGFile::getiDCTImage()
       
    36 {
       
    37     readHeader();
       
    38 
       
    39     /* Set our JPEG decompression parameters */
       
    40     srcinfo->dct_method = JDCT_FLOAT;
       
    41 
       
    42     /* jpeglib don't do any postprocessing (scaling/colorq). */
       
    43     srcinfo->raw_data_out = TRUE;
       
    44     
       
    45     /* Start decompression of pixels */
       
    46     jpeg_start_decompress(srcinfo);
       
    47 
       
    48     unsigned int nplanes = srcinfo->num_components;
       
    49 
       
    50     /* Create the planes */
       
    51     FloatPlane *planes = new FloatPlane[nplanes];
       
    52     unsigned int width[nplanes];
       
    53     unsigned int height[nplanes];
       
    54     unsigned int max_width_in_blocks = 0;
       
    55 
       
    56     /* Get the pointers to the planes */
       
    57     float *bmp[srcinfo->out_color_components];
       
    58     for (unsigned int i=0; i < nplanes; i++)
       
    59     {
       
    60         /* get the dimensions for every plane*/
       
    61         width[i] = srcinfo->comp_info[i].downsampled_width;
       
    62         height[i] = srcinfo->comp_info[i].downsampled_height;
       
    63 
       
    64         if (srcinfo->comp_info[i].width_in_blocks > max_width_in_blocks)
       
    65             max_width_in_blocks = srcinfo->comp_info[i].width_in_blocks;
       
    66         /* Allocate and prepare bmp[] */
       
    67         planes[i].allocate(width[i], height[i]);
       
    68         bmp[i] = planes[i].ptr;
       
    69     }
       
    70 
       
    71     /* The function jpeg_read_raw_data will return an MCU per call */
       
    72     int nscanlines = srcinfo->max_v_samp_factor*DCTSIZE;
       
    73 
       
    74     /* Get memory for the buffer scanline pointers */
       
    75     JSAMPARRAY *scanplanes = new JSAMPARRAY[nplanes];
       
    76 
       
    77     /* Get memory for each scanline in the buffer */
       
    78     for (unsigned int plane = 0; plane < nplanes; ++plane)
       
    79     {
       
    80         scanplanes[plane] = new JSAMPROW[nscanlines];
       
    81         for (int isl = 0; isl < nscanlines; ++isl)
       
    82             scanplanes[plane][isl] = new JSAMPLE[max_width_in_blocks * DCTSIZE];
       
    83     }
       
    84 
       
    85     unsigned int row[nplanes];
       
    86     unsigned int div_v_factor[nplanes];
       
    87     for (unsigned int plane = 0; plane < nplanes; ++plane)
       
    88     {
       
    89         row[plane] = 0;
       
    90         div_v_factor[plane] = srcinfo->max_v_samp_factor /
       
    91             srcinfo->comp_info[plane].v_samp_factor;
       
    92     }
       
    93 
       
    94     while (srcinfo->output_scanline < srcinfo->output_height) {
       
    95         int read_scanlines =
       
    96             jpeg_read_raw_data(srcinfo, scanplanes, nscanlines);
       
    97         for (unsigned int plane = 0; plane < nplanes; ++plane)
       
    98         {
       
    99             if (row[plane] >= height[plane])
       
   100                 continue;
       
   101             for (int isl = 0; isl < (read_scanlines / (int) div_v_factor[plane]); ++isl)
       
   102             {
       
   103                 for (unsigned int column = 0; column < width[plane];
       
   104                     ++column) {
       
   105                     bmp[plane][row[plane] * width[plane] + column] =
       
   106                         scanplanes[plane][isl][column];
       
   107                 }
       
   108             ++row[plane];
       
   109             }
       
   110         }
       
   111     }
       
   112 
       
   113     jpeg_destroy_decompress(srcinfo);
       
   114 
       
   115     fclose(inputh);
       
   116 
       
   117     Image *i = new Image(planes, nplanes);
       
   118 
       
   119     delete[] planes;
       
   120     for (unsigned int plane = 0; plane < nplanes; ++plane)
       
   121     {
       
   122         for (int isl = 0; isl < nscanlines; ++isl)
       
   123             delete[] scanplanes[plane][isl];
       
   124         delete[] scanplanes[plane];
       
   125     }
       
   126     delete[] scanplanes;
       
   127 
       
   128     return i;
       
   129 }
       
   130 
       
   131 Image *JPEGFile::getUnpackedImage()
       
   132 {
       
   133     readHeader();
       
   134 
       
   135     /* Set our JPEG decompression parameters */
       
   136     srcinfo->do_fancy_upsampling = 1;
       
   137     srcinfo->dct_method = JDCT_FLOAT;
       
   138 
       
   139     /* Get the number of planes */
       
   140     if (srcinfo->num_components == 1 &&
       
   141             srcinfo->jpeg_color_space == JCS_GRAYSCALE) {
       
   142         srcinfo->out_color_components = 1;
       
   143         srcinfo->out_color_space = JCS_GRAYSCALE;
       
   144     }
       
   145     else {
       
   146         srcinfo->out_color_components = 3;
       
   147         srcinfo->out_color_space = JCS_RGB;
       
   148     }
       
   149 
       
   150     /* Start decompression of pixels */
       
   151     jpeg_start_decompress(srcinfo);
       
   152 
       
   153     unsigned int nplanes = srcinfo->out_color_components;
       
   154 
       
   155     /* Create the planes */
       
   156     FloatPlane *planes = new FloatPlane[nplanes];
       
   157 
       
   158     /* Get the pointers to the planes */
       
   159     float *bmp[srcinfo->out_color_components];
       
   160     for (unsigned int i=0; i < nplanes; i++)
       
   161     {
       
   162         planes[i].allocate(srcinfo->output_width, srcinfo->output_height);
       
   163         bmp[i] = planes[i].ptr;
       
   164     }
       
   165 
       
   166     /* Get the recommended number of buffer scanlines */
       
   167     int nscanlines = srcinfo->rec_outbuf_height;
       
   168 
       
   169     /* Get memory for the buffer scanline pointers */
       
   170     JSAMPROW *scanlines = new JSAMPROW[nscanlines];
       
   171 
       
   172     /* Get memory for each scanline in the buffer */
       
   173     for (int isl = 0; isl < nscanlines; ++isl)
       
   174     {
       
   175         scanlines[isl] = new JSAMPLE[srcinfo->output_width * nplanes];
       
   176     }
       
   177 
       
   178     int row = 0;
       
   179     while (srcinfo->output_scanline < srcinfo->output_height) {
       
   180         int read_scanlines =
       
   181             jpeg_read_scanlines(srcinfo, scanlines, nscanlines);
       
   182         for (int isl = 0; isl < read_scanlines; ++isl)
       
   183         {
       
   184             for (unsigned int column = 0; column < srcinfo->output_width;
       
   185                     ++column) {
       
   186                 for (unsigned int plane = 0; plane < nplanes; plane++)
       
   187                     bmp[plane][row * srcinfo->output_width + column] =
       
   188                         scanlines[isl][column * srcinfo->out_color_components
       
   189                         + plane];
       
   190             }
       
   191             ++row;
       
   192         }
       
   193     }
       
   194 
       
   195     jpeg_destroy_decompress(srcinfo);
       
   196 
       
   197     fclose(inputh);
       
   198 
       
   199     Image *i = new Image(planes, nplanes);
       
   200 
       
   201     delete[] planes;
       
   202     for (int isl = 0; isl < nscanlines; ++isl)
       
   203         delete[] scanlines[isl];
       
   204     delete[] scanlines;
       
   205 
       
   206     return i;
       
   207 }
       
   208 
       
   209 JPEGFile::~JPEGFile()
       
   210 {
       
   211     delete[] filename;
       
   212     delete srcinfo;
       
   213     delete jsrcerr;
       
   214 }