degate  0.1.2
JPEGReader.h
Go to the documentation of this file.
00001 /* -*-c++-*-
00002 
00003  This file is part of the IC reverse engineering tool degate.
00004 
00005  Copyright 2008, 2009, 2010 by Martin Schobert
00006 
00007  Degate is free software: you can redistribute it and/or modify
00008  it under the terms of the GNU General Public License as published by
00009  the Free Software Foundation, either version 3 of the License, or
00010  any later version.
00011 
00012  Degate is distributed in the hope that it will be useful,
00013  but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  GNU General Public License for more details.
00016 
00017  You should have received a copy of the GNU General Public License
00018  along with degate. If not, see <http://www.gnu.org/licenses/>.
00019 
00020  */
00021 
00022 #ifndef __JPEGREADER_H__
00023 #define __JPEGREADER_H__
00024 
00025 #include <list>
00026 #include <memory>
00027 #include <jpeglib.h>
00028 
00029 #include "StoragePolicies.h"
00030 #include "ImageReaderBase.h"
00031 
00032 namespace degate {
00033 
00034 
00035   /**
00036    * The JPEGReader parses jpeg images.
00037    */
00038 
00039   template<class ImageType>
00040   class JPEGReader : public ImageReaderBase<ImageType> {
00041 
00042   private:
00043 
00044     unsigned char * image_buffer;
00045     int depth;
00046 
00047   public:
00048 
00049     using ImageReaderBase<ImageType>::get_filename;
00050     using ImageReaderBase<ImageType>::set_width;
00051     using ImageReaderBase<ImageType>::set_height;
00052     using ImageReaderBase<ImageType>::get_width;
00053     using ImageReaderBase<ImageType>::get_height;
00054 
00055     JPEGReader(std::string const& filename) :
00056       ImageReaderBase<ImageType>(filename),
00057       image_buffer(NULL) {}
00058 
00059     ~JPEGReader() {
00060       if(image_buffer != NULL) free(image_buffer);
00061     }
00062 
00063     bool read();
00064 
00065     bool get_image(std::shared_ptr<ImageType>);
00066 
00067 
00068   };
00069 
00070   template<class ImageType>
00071   bool JPEGReader<ImageType>::read() {
00072 
00073     struct jpeg_decompress_struct cinfo;
00074     struct jpeg_error_mgr jerr;
00075     FILE * infile;     /* source file */
00076     depth = 0;
00077 
00078     JSAMPARRAY buffer; /* Output row buffer */
00079     int row_stride;    /* physical row width in output buffer */
00080     unsigned int p = 0;
00081 
00082     if ((infile = fopen(get_filename().c_str(), "rb")) == NULL) {
00083       debug(TM, "can't open %s\n", get_filename().c_str());
00084       return false;
00085     }
00086 
00087     cinfo.err = jpeg_std_error(&jerr);
00088 
00089     jpeg_create_decompress(&cinfo);
00090     jpeg_stdio_src(&cinfo, infile);
00091 
00092     jpeg_read_header(&cinfo, TRUE);
00093     jpeg_start_decompress(&cinfo);
00094 
00095     set_width(cinfo.output_width);
00096     set_height(cinfo.output_height);
00097     depth = cinfo.num_components;
00098 
00099     debug(TM, "Reading image with size: %d x %d", get_width(), get_height());
00100 
00101     image_buffer = (unsigned char *)malloc(depth * get_width() * get_height());
00102 
00103     if(image_buffer != NULL) {
00104 
00105       row_stride = cinfo.output_width * cinfo.output_components;
00106       buffer = (*cinfo.mem->alloc_sarray)
00107         ((j_common_ptr) &cinfo, JPOOL_IMAGE, row_stride, 1);
00108 
00109       printf("Row stride is %d\n",row_stride);
00110       while (cinfo.output_scanline < cinfo.output_height) {
00111         jpeg_read_scanlines(&cinfo, buffer, 1);
00112 
00113         memcpy(&image_buffer[p],buffer[0],row_stride);
00114         p+=row_stride;
00115         //        put_scanline_someplace(buffer[0], row_stride);
00116       }
00117 
00118       printf("Image read\n");
00119     }
00120 
00121     jpeg_finish_decompress(&cinfo);
00122     jpeg_destroy_decompress(&cinfo);
00123     fclose(infile);
00124 
00125     return true;
00126   }
00127 
00128   template<class ImageType>
00129   bool JPEGReader<ImageType>::get_image(std::shared_ptr<ImageType> img) {
00130 
00131     if(img == NULL) return false;
00132 
00133     for(unsigned int y = 0; y < get_height(); y++) {
00134       for(unsigned int x = 0; x < get_width(); x++) {
00135 
00136         uint8_t v1, v2, v3;
00137         if(depth == 1) {
00138           v1 = v2 = v3 = image_buffer[(y * get_width() + x)];
00139         }
00140         else if(depth == 3) {
00141           v1 = image_buffer[depth * (y * get_width() + x)];
00142           v2 = image_buffer[depth * (y * get_width() + x) + 1];
00143           v3 = image_buffer[depth * (y * get_width() + x) + 2];
00144         }
00145         else throw std::runtime_error("Unexpected number of channels in JPG file.");
00146 
00147         img->set_pixel(x, y, MERGE_CHANNELS(v1, v2, v3, 0xff));
00148 
00149       }
00150     }
00151 
00152     return true;
00153   }
00154 
00155 
00156 }
00157 
00158 #endif