Go to the documentation of this file.00001
00007 #include "ImageConverter.h"
00008
00009 #include <iostream>
00010
00011 extern "C" {
00012 #define XMD_H
00013 #include <jpeglib.h>
00014 }
00015 #include <png.h>
00016
00017
00018 using namespace std;
00019 using namespace hrp;
00020
00021
00022
00023
00033
00034 bool ImageConverter::initializeSFImage( )
00035 {
00036 image->width = 0;
00037 image->height = 0;
00038 image->numComponents = 0;
00039 image->pixels.clear();
00040
00041 return true;
00042 }
00043
00044
00045
00046
00059
00060 SFImage* ImageConverter::convert( string url )
00061 {
00062
00063 string ext = url.substr( url.rfind( '.' ) );
00064
00065
00066 transform( ext.begin(), ext.end(), ext.begin(), (int(*)(int))tolower );
00067
00068
00069 if( !ext.compare( ".png" ) )
00070 {
00071 if(loadPNG( url ))
00072 return image;
00073 }
00074 else if( !ext.compare( ".jpg" ) )
00075 {
00076 if(loadJPEG( url ))
00077 return image;
00078 }
00079 else
00080 {
00081
00082 }
00083
00084 image->height = 0;
00085 image->width = 0;
00086 image->numComponents = 0;
00087 image->pixels.resize(0);
00088 return image;
00089 }
00090
00091
00092
00093
00103
00104 bool
00105 ImageConverter::loadPNG(
00106 string & filePath
00107 )
00108 {
00109 initializeSFImage( );
00110
00111 FILE * fp;
00112
00113 try
00114 {
00115
00116 fp = fopen( filePath.c_str(), "rb" );
00117 if( !fp ) throw "File open error.";
00118
00119
00120
00121 png_size_t number = 8;
00122 png_byte header[8];
00123 int is_png;
00124
00125 fread( header, 1, number, fp );
00126 is_png = !png_sig_cmp( header, 0, number );
00127 if( !is_png ) throw "File is not png.";
00128
00129
00130
00131 png_structp pPng;
00132
00133 pPng = png_create_read_struct( PNG_LIBPNG_VER_STRING, NULL, NULL, NULL );
00134 if( !pPng ) throw "Failed to create png_struct";
00135
00136
00137
00138 png_infop pInfo;
00139
00140 pInfo = png_create_info_struct( pPng );
00141 if( !pInfo )
00142 {
00143 png_destroy_read_struct( &pPng, NULL, NULL );
00144 throw "Failed to create png_info";
00145 }
00146
00147
00148
00149 png_init_io( pPng, fp );
00150 png_set_sig_bytes( pPng, (int)number );
00151
00152 png_read_info(pPng, pInfo);
00153 png_uint_32 width = png_get_image_width( pPng, pInfo );
00154 png_uint_32 height = png_get_image_height( pPng, pInfo );
00155 png_byte color_type = png_get_color_type( pPng, pInfo );
00156 png_byte depth = png_get_bit_depth( pPng, pInfo );
00157
00158 if (png_get_valid( pPng, pInfo, PNG_INFO_tRNS))
00159 png_set_tRNS_to_alpha(pPng);
00160 if (depth < 8)
00161 png_set_packing(pPng);
00162
00163 int numComponents;
00164 switch( color_type )
00165 {
00166 case PNG_COLOR_TYPE_GRAY:
00167 numComponents = 1;
00168 if(depth < 8)
00169 #if PNG_LIBPNG_VER_MINOR >= 4
00170 png_set_expand_gray_1_2_4_to_8(pPng);
00171 #else
00172 png_set_gray_1_2_4_to_8(pPng);
00173 #endif
00174 break;
00175
00176 case PNG_COLOR_TYPE_GRAY_ALPHA:
00177 numComponents = 2;
00178 if (depth == 16)
00179 png_set_strip_16(pPng);
00180 break;
00181
00182 case PNG_COLOR_TYPE_RGB:
00183 numComponents = 3;
00184 if (depth == 16)
00185 png_set_strip_16(pPng);
00186 break;
00187
00188 case PNG_COLOR_TYPE_RGB_ALPHA:
00189 numComponents = 4;
00190 if (depth == 16)
00191 png_set_strip_16(pPng);
00192 break;
00193
00194 case PNG_COLOR_TYPE_PALETTE:
00195 png_set_palette_to_rgb(pPng);
00196 numComponents = 3;
00197 break;
00198
00199 default:
00200 numComponents = 1;
00201
00202
00203 }
00204
00205 png_read_update_info( pPng, pInfo );
00206
00207 unsigned char** row_pointers;
00208 row_pointers = (png_bytepp)malloc(height * sizeof(png_bytep));
00209 png_uint_32 rowbytes = png_get_rowbytes(pPng, pInfo);
00210 image->pixels.resize(rowbytes*height);
00211 for(unsigned int i=0; i<height; i++)
00212 row_pointers[i] = &(image->pixels[i*rowbytes]);
00213
00214 png_read_image(pPng, row_pointers);
00215
00216 image->width = width;
00217 image->height = height;
00218 image->numComponents = numComponents;
00219
00220 free(row_pointers);
00221 png_destroy_read_struct( &pPng, &pInfo, NULL );
00222
00223 fclose(fp);
00224
00225 }
00226
00227 catch( char * str )
00228 {
00229 cout << "PNG read error: " << str << '\n';
00230 if( fp ) fclose( fp );
00231 return false;
00232 }
00233
00234 return true;
00235 }
00236
00237
00238
00239
00249
00250 bool
00251 ImageConverter::loadJPEG(
00252 string & filePath )
00253 {
00254 initializeSFImage( );
00255
00256 FILE * fp;
00257
00258 try
00259 {
00260
00261 fp = fopen( filePath.c_str(), "rb" );
00262 if( !fp ) throw "File open error.";
00263
00264
00265 struct jpeg_decompress_struct cinfo;
00266 struct jpeg_error_mgr jerr;
00267
00268
00269 cinfo.err = jpeg_std_error( &jerr );
00270 jpeg_create_decompress( &cinfo );
00271
00272
00273
00274 jpeg_stdio_src( &cinfo, fp );
00275
00276
00277 (void)jpeg_read_header( &cinfo, TRUE );
00278
00279
00280
00281
00282
00283
00284 (void)jpeg_start_decompress( &cinfo );
00285
00286
00287
00288 image->width = cinfo.output_width;
00289 image->height = cinfo.output_height;
00290 image->numComponents = cinfo.out_color_components;
00291
00292 JSAMPARRAY row_pointers;
00293 row_pointers = (JSAMPARRAY)malloc( sizeof( JSAMPROW ) * image->height );
00294 image->pixels.resize(cinfo.output_components * image->width * image->height);
00295 for (int i = 0; i < image->height; i++ )
00296 row_pointers[i] = &(image->pixels[i * cinfo.output_components * image->width]);
00297
00298 while( cinfo.output_scanline < cinfo.output_height ) {
00299 jpeg_read_scanlines( &cinfo,
00300 row_pointers + cinfo.output_scanline,
00301 cinfo.output_height - cinfo.output_scanline
00302 );
00303 }
00304
00305 free(row_pointers);
00306
00307
00308 (void)jpeg_finish_decompress( &cinfo );
00309
00310
00311
00312 jpeg_destroy_decompress( &cinfo );
00313
00314
00315 fclose( fp );
00316 }
00317
00318 catch( char * str )
00319 {
00320 cout << "JPEG read error: " << str << '\n';
00321 if( fp ) fclose( fp );
00322 return false;
00323 }
00324
00325 return true;
00326 }