|
degate 0.1.1
|
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 <tr1/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::tr1::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::tr1::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
1.7.4