ImageConverter.cpp
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    // SFImageの作成 //
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       // cout << "ImageTexture read error: unsupported format." << '\n';
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 //==================================================================================================bool
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         // png_struct 構造体の初期化 //
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         // png_info 構造体の初期化 //
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           //  throw "Unsupported color type.";
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 //==================================================================================================bool
00250 bool
00251 ImageConverter::loadJPEG(
00252     string &    filePath )
00253 {
00254     initializeSFImage( );
00255 
00256     FILE *  fp;
00257 
00258     try
00259     {
00260         // File open
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         // Step 1: allocate and initialize JPEG decompression object
00269         cinfo.err = jpeg_std_error( &jerr );
00270         jpeg_create_decompress( &cinfo );
00271 
00272 
00273         // Step 2: specify data source (eg, a file)
00274         jpeg_stdio_src( &cinfo, fp );
00275 
00276         // Step 3: read file parameters with jpeg_read_header()
00277         (void)jpeg_read_header( &cinfo, TRUE );
00278 
00279 
00280         // Step 4: set parameters for decompression
00281 
00282 
00283         // Step 5: Start decompression
00284         (void)jpeg_start_decompress( &cinfo );
00285 
00286 
00287         // get image attribute
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         // Step 7: Finish decompression
00308         (void)jpeg_finish_decompress( &cinfo );
00309 
00310 
00311         // Step 8: Release JPEG decompression object
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 }


openhrp3
Author(s): AIST, General Robotix Inc., Nakamura Lab of Dept. of Mechano Informatics at University of Tokyo
autogenerated on Thu Apr 11 2019 03:30:17