00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #include "OSDLImage.h"
00028
00029 #include "OSDLVideo.h"
00030 #include "OSDLUtils.h"
00031 #include "OSDLSurface.h"
00032 #include "OSDLPixel.h"
00033
00034
00035
00036 #ifdef OSDL_USES_CONFIG_H
00037 #include <OSDLConfig.h>
00038 #endif // OSDL_USES_CONFIG_H
00039
00040 #if OSDL_ARCH_NINTENDO_DS
00041 #include "OSDLConfigForNintendoDS.h"
00042 #endif // OSDL_ARCH_NINTENDO_DS
00043
00044
00045
00046 #if OSDL_USES_SDL_IMAGE
00047 #include "SDL_image.h"
00048 #endif // OSDL_USES_SDL_IMAGE
00049
00050 #if OSDL_USES_LIBPNG
00051
00052
00053
00054
00055
00056 #define _FILE_OFFSET_BITS 64
00057 #include "png.h"
00058 #endif // OSDL_USES_LIBPNG
00059
00060
00061
00062 #include "OSDLIncludeCorrecter.h"
00063
00064
00065 using std::string ;
00066
00067 using namespace Ceylan::Log ;
00068 using namespace Ceylan::System ;
00069
00070 using namespace OSDL::Video ;
00071 using namespace OSDL::Video::Pixels ;
00072 using namespace OSDL::Video::TwoDimensional ;
00073
00074
00075
00077
00078 const string Image::JPGTag = "JPG" ;
00079 const string Image::PNGTag = "PNG" ;
00080
00081
00082
00084
00085 const string Image::BMPTag = "BMP" ;
00086 const string Image::GIFTag = "GIF" ;
00087 const string Image::LBMTag = "LBM" ;
00088 const string Image::PCXTag = "PCX" ;
00089 const string Image::PNMTag = "PNM" ;
00090 const string Image::TGATag = "TGA" ;
00091 const string Image::XPMTag = "XPM" ;
00092
00093
00094
00106 ImageException::ImageException( const std::string & reason ) :
00107 VideoException( reason )
00108 {
00109
00110 }
00111
00112
00113
00114 ImageException::~ImageException() throw()
00115 {
00116
00117 }
00118
00119
00120
00121
00126 Image::Image( const string & imageFilename, bool preload,
00127 bool convertToDisplayFormat, bool convertWithAlpha ) :
00128 Ceylan::LoadableWithContent<Surface>( imageFilename ),
00129 _convertToDisplayFormat( convertToDisplayFormat ),
00130 _convertWithAlpha( convertWithAlpha )
00131 {
00132
00133 if ( preload )
00134 {
00135
00136 try
00137 {
00138
00139 load() ;
00140
00141 }
00142 catch( const Ceylan::LoadableException & e )
00143 {
00144
00145 throw ImageException( "Image constructor failed while preloading: "
00146 + e.toString() ) ;
00147
00148 }
00149
00150 }
00151
00152 }
00153
00154
00155
00156 Image::~Image() throw()
00157 {
00158
00159 try
00160 {
00161
00162 if ( hasContent() )
00163 unload() ;
00164
00165 }
00166 catch( const Ceylan::LoadableException & e )
00167 {
00168
00169 LogPlug::error( "Image destructor failed while unloading: "
00170 + e.toString() ) ;
00171
00172 }
00173
00174
00175
00176 }
00177
00178
00179
00180
00181
00182
00183
00184
00185 bool Image::load()
00186 {
00187
00188 if ( hasContent() )
00189 return false ;
00190
00191 try
00192 {
00193
00194 _content = & Surface::LoadImage( _contentPath, _convertToDisplayFormat,
00195 _convertWithAlpha ) ;
00196
00197 }
00198 catch( const Ceylan::Exception & e )
00199 {
00200
00201 throw Ceylan::LoadableException( "Image::load failed: "
00202 "unable to load from '" + _contentPath + "': " + e.toString() ) ;
00203
00204 }
00205
00206
00207 return true ;
00208
00209 }
00210
00211
00212
00213 bool Image::unload()
00214 {
00215
00216 if ( ! hasContent() )
00217 return false ;
00218
00219
00220
00221 delete _content ;
00222 _content = 0 ;
00223
00224 return true ;
00225
00226 }
00227
00228
00229
00230 const std::string Image::toString( Ceylan::VerbosityLevels level ) const
00231 {
00232
00233 string res = "Image whose content is read from file '" + _contentPath
00234 + "'. The image is " ;
00235
00236 if ( _content == 0 )
00237 res += "not loaded" ;
00238 else
00239 res += "loaded: surface content is '" + _content->toString( level )
00240 + "'" ;
00241
00242 res += ". On loading, it is " ;
00243
00244 if ( _convertToDisplayFormat )
00245 {
00246
00247 res += string( "converted to the screen format, with " ) +
00248 ( _convertWithAlpha ? "an" : "no" ) + string( " alpha channel" ) ;
00249
00250 }
00251 else
00252 {
00253
00254 res += "not converted to the screen format." ;
00255 }
00256
00257 return res ;
00258
00259 }
00260
00261
00262
00263
00264
00265
00266 Surface & Image::LoadIcon( const string & filename,
00267 Pixels::ColorElement ** mask )
00268 {
00269
00270
00271
00272 #if OSDL_DEBUG_IMAGE
00273 LogPlug::debug( "Loading icon." ) ;
00274 #endif // OSDL_DEBUG_IMAGE
00275
00276
00277
00278
00279 Surface & iconSurface = Surface::LoadImage( filename,
00280 false, false ) ;
00281
00282
00283 #if OSDL_DEBUG_IMAGE
00284 LogPlug::debug( "Icon loaded." ) ;
00285
00286 LogPlug::debug( "Displaying icon informations: "
00287 + iconSurface.toString() ) ;
00288 #endif // OSDL_DEBUG_IMAGE
00289
00290 if ( iconSurface.getPixelFormat().palette == 0 )
00291 {
00292
00293 delete & iconSurface ;
00294 throw ImageException( "Image::LoadIcon: image " + filename
00295 + " does not seem to have a palette as it should." ) ;
00296
00297 }
00298
00299
00300 iconSurface.setColorKey( Surface::ColorkeyBlit,
00301 * ( (Pixels::ColorElement *) iconSurface.getPixels() ) ) ;
00302
00303 ColorElement * pixels = static_cast<ColorElement *>(
00304 iconSurface.getPixels() ) ;
00305
00306 #if OSDL_DEBUG_IMAGE
00307
00308 LogPlug::debug( "Image::LoadIcon: index of upper left pixel is "
00309 + Ceylan::toString( static_cast<unsigned short>( *pixels ) ) ) ;
00310
00311 LogPlug::debug( "Image::LoadIcon: transparent pixel is: "
00312 + Pixels::toString(
00313 iconSurface.getPixelFormat().palette->colors[*pixels] ) ) ;
00314
00315
00316 LogPlug::debug(
00317 "Creating image mask (one bit per image pixel, rounded up)" ) ;
00318
00319 #endif // OSDL_DEBUG_IMAGE
00320
00321 int maskLen = ( iconSurface.getWidth() * iconSurface.getHeight() + 7 ) / 8 ;
00322 ColorElement * constructedMask = new ColorElement[ maskLen ] ;
00323
00324 if ( constructedMask == 0 )
00325 {
00326 delete & iconSurface ;
00327 throw ImageException( "Image::LoadIcon: not enough memory." ) ;
00328 }
00329
00330 ::memset( constructedMask, 0, maskLen ) ;
00331
00332 int paletteIndex ;
00333 int maskIndex ;
00334
00335
00336 for ( Coordinate i = 0; i < iconSurface.getHeight(); i++ )
00337 {
00338
00339
00340
00341 for ( Coordinate j = 0; j < iconSurface.getWidth(); j++ )
00342 {
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353 paletteIndex = i * iconSurface.getPitch() + j ;
00354 maskIndex = i * iconSurface.getWidth() + j ;
00355
00356
00357
00358
00359
00360
00361 if ( pixels[ paletteIndex ] != *pixels )
00362 constructedMask[ maskIndex >>3 ] |=
00363 1 << ( 7 - ( maskIndex & 7) ) ;
00364 }
00365
00366 }
00367
00368 #if OSDL_DEBUG_IMAGE
00369 LogPlug::debug( "Icon scanned." ) ;
00370 #endif // OSDL_DEBUG_IMAGE
00371
00372 *mask = constructedMask ;
00373
00374 #if OSDL_DEBUG_IMAGE
00375 LogPlug::debug( "Icon fully loaded." ) ;
00376 #endif // OSDL_DEBUG_IMAGE
00377
00378 return iconSurface ;
00379
00380 }
00381
00382
00383
00384 void Image::Load( Surface & targetSurface, const std::string & filename,
00385 bool blitOnly, bool convertToDisplay, bool convertWithAlpha )
00386 {
00387
00388 #if OSDL_USES_SDL_IMAGE
00389
00390 #if OSDL_DEBUG_IMAGE
00391 LogPlug::debug( "Image::Load: loading image from " + filename ) ;
00392 #endif // OSDL_DEBUG_IMAGE
00393
00394
00395
00396 if ( ! File::Exists( filename ) )
00397 throw ImageException( "Image::Load: unable to load image file '"
00398 + filename + "': file not found." ) ;
00399
00400
00401
00402
00403
00404
00405
00406
00407 SDL_Surface * image ;
00408
00409 try
00410 {
00411
00412
00413 Ceylan::System::File & imageFile = File::Open( filename ) ;
00414
00415 image = IMG_Load_RW( & Utils::createDataStreamFrom( imageFile ),
00416 true ) ;
00417
00418 }
00419 catch( const Ceylan::Exception & e )
00420 {
00421
00422 throw ImageException( "Image::Load failed: unable to load from '"
00423 + filename + "': " + e.toString() ) ;
00424
00425 }
00426
00427 if ( image == 0 )
00428 throw ImageException(
00429 "Image::Load: unable to load image stored in '"
00430 + filename + "': " + string( IMG_GetError() ) ) ;
00431
00432 #if OSDL_DEBUG_IMAGE
00433 LogPlug::debug( "Image loaded." ) ;
00434 #endif // OSDL_DEBUG_IMAGE
00435
00436
00437
00438
00439
00440
00441
00442 if ( convertToDisplay )
00443 {
00444
00445 if ( ! VideoModule::IsDisplayInitialized() )
00446 throw ImageException(
00447 "Image::Load called with request to convert surface "
00448 "to display, whereas display not initialized "
00449 "(VideoModule::setMode never called)." ) ;
00450
00451 SDL_Surface * formattedImage ;
00452
00453
00454
00455
00456
00457
00458
00459 if ( convertWithAlpha )
00460 {
00461
00462 #if OSDL_DEBUG_IMAGE
00463 LogPlug::debug(
00464 "Converting image to display format, with alpha." ) ;
00465 #endif // OSDL_DEBUG_IMAGE
00466
00467 formattedImage = SDL_DisplayFormatAlpha( image ) ;
00468
00469 }
00470 else
00471 {
00472
00473 #if OSDL_DEBUG_IMAGE
00474 LogPlug::debug( "Converting image to display format, no alpha." ) ;
00475 #endif // OSDL_DEBUG_IMAGE
00476
00477 formattedImage = SDL_DisplayFormat( image ) ;
00478
00479 }
00480
00481 SDL_FreeSurface( image ) ;
00482
00483 image = formattedImage ;
00484
00485 if ( image == 0 )
00486 throw ImageException(
00487 "Unable to convert to display the image loaded from "
00488 + filename + "." ) ;
00489
00490 }
00491
00492
00493
00494
00495
00496
00497
00498 if ( blitOnly )
00499 {
00500
00501
00502 #if OSDL_DEBUG_IMAGE
00503 LogPlug::debug( "Blitting loaded image to already existing surface." ) ;
00504 #endif // OSDL_DEBUG_IMAGE
00505
00506 #if OSDL_DEBUG
00507
00508 if ( ! targetSurface.isInternalSurfaceAvailable() )
00509 throw ImageException( "Image::Load: trying to blit image "
00510 "whereas target SDL_surface pointer is null" ) ;
00511
00512 #endif // OSDL_DEBUG
00513
00514
00515 #if OSDL_DEBUG
00516
00517
00518
00519 if ( targetSurface.isLocked() )
00520 throw ImageException( "Image::Load: trying to blit an image "
00521 "whereas target surface is locked" ) ;
00522
00523 #endif // OSDL_DEBUG
00524
00525 int result = SDL_BlitSurface( image, 0,
00526 & targetSurface.getSDLSurface(), 0 ) ;
00527
00528 if ( result == -1)
00529 throw ImageException( "Image::Load: error in blit: "
00530 + Utils::getBackendLastError() ) ;
00531
00532 if ( result == -2 )
00533 throw ImageException(
00534 "Image::Load: video memory was lost during blit." ) ;
00535
00536
00537
00538
00539
00540
00541
00542 SDL_FreeSurface( image ) ;
00543
00544 }
00545 else
00546 {
00547
00548 #if OSDL_DEBUG_IMAGE
00549 LogPlug::debug( "Replacing already existing image by loaded one." ) ;
00550 #endif // OSDL_DEBUG
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560
00561 targetSurface.setSDLSurface( * image ) ;
00562
00563 }
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576 #if OSDL_DEBUG_IMAGE
00577 LogPlug::debug( "Image loaded." ) ;
00578 #endif // OSDL_DEBUG
00579
00580 #else // OSDL_USES_SDL_IMAGE
00581
00582 throw ImageException( "Image::Load failed: "
00583 "no SDL_image support available" ) ;
00584
00585 #endif // OSDL_USES_SDL_IMAGE
00586
00587 }
00588
00589
00590
00591 void Image::LoadJPG( Surface & targetSurface, const std::string & filename,
00592 bool blitOnly, bool convertToDisplay, bool convertWithAlpha )
00593 {
00594
00595 #if OSDL_USES_SDL_IMAGE
00596
00597 if ( ! File::Exists( filename ) )
00598 throw ImageException( "Unable to load JPG file "
00599 + filename + ": file not found." ) ;
00600
00601 SDL_Surface * image ;
00602
00603 try
00604 {
00605
00606
00607 Ceylan::System::File & imageFile = File::Open( filename ) ;
00608
00609 image = IMG_LoadTyped_RW( & Utils::createDataStreamFrom( imageFile ),
00610 true,
00611 const_cast<char *>( JPGTag.c_str() ) ) ;
00612
00613 }
00614 catch( const Ceylan::Exception & e )
00615 {
00616
00617 throw ImageException( "Image::LoadJPG failed: unable to load from '"
00618 + filename + "': " + e.toString() ) ;
00619
00620 }
00621
00622 if ( image == 0 )
00623 throw ImageException( "Unable to load JPG image stored in " + filename
00624 + " thanks to IMG_LoadTyped_RW: " + string( IMG_GetError() ) ) ;
00625
00626
00627
00628
00629
00630
00631
00632
00633 if ( convertToDisplay )
00634 {
00635
00636 if ( ! VideoModule::IsDisplayInitialized() )
00637 throw ImageException(
00638 "Image::LoadJPG called with request to convert surface "
00639 "to display, whereas display not initialized "
00640 "(VideoModule::setMode never called)." ) ;
00641
00642 SDL_Surface * formattedImage ;
00643
00644
00645
00646
00647
00648
00649
00650 if ( convertWithAlpha )
00651 {
00652
00653 formattedImage = SDL_DisplayFormatAlpha( image ) ;
00654
00655 }
00656 else
00657 {
00658
00659 formattedImage = SDL_DisplayFormat( image ) ;
00660
00661 }
00662
00663 SDL_FreeSurface( image ) ;
00664
00665 image = formattedImage ;
00666
00667 }
00668
00669
00670
00671
00672
00673
00674
00675 if ( blitOnly )
00676 {
00677
00678
00679
00680 #if OSDL_DEBUG
00681
00682 if ( ! targetSurface.isInternalSurfaceAvailable() )
00683 throw ImageException( "Image::LoadJPG: trying to blit image "
00684 "whereas target SDL_surface pointer is null" ) ;
00685
00686 #endif // OSDL_DEBUG
00687
00688
00689 #if OSDL_DEBUG
00690
00691
00692
00693 if ( targetSurface.isLocked() )
00694 throw ImageException( "Image::LoadJPG: trying to blit an image "
00695 "whereas target surface is locked" ) ;
00696
00697 #endif // OSDL_DEBUG
00698
00699
00700 int result = SDL_BlitSurface( image, 0,
00701 & targetSurface.getSDLSurface(), 0 ) ;
00702
00703 if ( result == -1)
00704 throw ImageException( "Image::LoadJPG: error in blit: "
00705 + Utils::getBackendLastError() ) ;
00706
00707 if ( result == -2 )
00708 throw ImageException(
00709 "Image::LoadJPG: video memory was lost during blit." ) ;
00710
00711
00712
00713
00714
00715
00716
00717
00718 SDL_FreeSurface( image ) ;
00719
00720 }
00721 else
00722 {
00723
00724
00725
00726
00727
00728
00729
00730
00731
00732
00733
00734 targetSurface.setSDLSurface( * image ) ;
00735 }
00736
00737
00738
00739
00740
00741
00742
00743
00744
00745
00746
00747
00748
00749 #else // OSDL_USES_SDL_IMAGE
00750
00751 throw ImageException( "Image::LoadJPG failed: "
00752 "no SDL_image support available" ) ;
00753
00754 #endif // OSDL_USES_SDL_IMAGE
00755
00756 }
00757
00758
00759
00760 void Image::LoadPNG( Surface & targetSurface, const std::string & filename,
00761 bool blitOnly, bool convertToDisplay, bool convertWithAlpha )
00762 {
00763
00764 #if OSDL_USES_SDL_IMAGE
00765
00766 if ( ! File::Exists( filename ) )
00767 throw ImageException( "Unable to load PNG file "
00768 + filename + ": file not found." ) ;
00769
00770 SDL_Surface * image ;
00771
00772 try
00773 {
00774
00775
00776 Ceylan::System::File & imageFile = File::Open( filename ) ;
00777
00778 image = IMG_LoadTyped_RW( & Utils::createDataStreamFrom( imageFile ),
00779 true,
00780 const_cast<char *>( PNGTag.c_str() ) ) ;
00781
00782 }
00783 catch( const Ceylan::Exception & e )
00784 {
00785
00786 throw ImageException( "Image::LoadPNG failed: unable to load from '"
00787 + filename + "': " + e.toString() ) ;
00788
00789 }
00790
00791 if ( image == 0 )
00792 throw ImageException( "Unable to load PNG image stored in "
00793 + filename + " thanks to IMG_LoadTyped_RW: "
00794 + string( IMG_GetError() ) ) ;
00795
00796
00797
00798
00799
00800
00801
00802
00803 if ( convertToDisplay )
00804 {
00805
00806 if ( ! VideoModule::IsDisplayInitialized() )
00807 throw ImageException(
00808 "Image::LoadPNG called with request to convert surface "
00809 "to display, whereas display not initialized "
00810 "(VideoModule::setMode never called)." ) ;
00811
00812 SDL_Surface * formattedImage ;
00813
00814
00815
00816
00817
00818
00819
00820 if ( convertWithAlpha )
00821 {
00822
00823 formattedImage = SDL_DisplayFormatAlpha( image ) ;
00824
00825 }
00826 else
00827 {
00828
00829 formattedImage = SDL_DisplayFormat( image ) ;
00830
00831 }
00832
00833 SDL_FreeSurface( image ) ;
00834
00835 image = formattedImage ;
00836
00837 }
00838
00839
00840
00841
00842
00843
00844
00845 if ( blitOnly )
00846 {
00847
00848
00849
00850 #if OSDL_DEBUG
00851
00852 if ( ! targetSurface.isInternalSurfaceAvailable() )
00853 throw ImageException( "Image::LoadPNG: trying to blit image "
00854 "whereas target SDL_surface pointer is null" ) ;
00855
00856 #endif // OSDL_DEBUG
00857
00858
00859 #if OSDL_DEBUG
00860
00861
00862
00863 if ( targetSurface.isLocked() )
00864 throw ImageException( "Image::LoadPNG: trying to blit an image "
00865 "whereas target surface is locked" ) ;
00866
00867 #endif // OSDL_DEBUG
00868
00869 int result = SDL_BlitSurface( image, 0,
00870 & targetSurface.getSDLSurface(), 0 ) ;
00871
00872 if ( result == -1)
00873 throw ImageException( "Image::LoadPNG: error in blit: "
00874 + Utils::getBackendLastError() ) ;
00875
00876 if ( result == -2 )
00877 throw ImageException(
00878 "Image::LoadPNG: video memory was lost during blit." ) ;
00879
00880
00881
00882
00883
00884
00885
00886 SDL_FreeSurface( image ) ;
00887
00888 }
00889 else
00890 {
00891
00892
00893
00894
00895
00896
00897
00898
00899
00900
00901
00902 targetSurface.setSDLSurface( * image ) ;
00903
00904 }
00905
00906
00907
00908
00909
00910
00911
00912
00913
00914
00915
00916
00917 #else // OSDL_USES_SDL_IMAGE
00918
00919 throw ImageException( "Image::LoadPNG failed: "
00920 "no SDL_image support available" ) ;
00921
00922 #endif // OSDL_USES_SDL_IMAGE
00923
00924 }
00925
00926
00927
00928 void Image::LoadBMP( Surface & targetSurface, const std::string & filename,
00929 bool blitOnly, bool convertToDisplay, bool convertWithAlpha )
00930 {
00931
00932 #if OSDL_USES_SDL_IMAGE
00933
00934 if ( ! File::Exists( filename ) )
00935 throw ImageException( "Unable to load BMP file "
00936 + filename + ": file not found." ) ;
00937
00938 SDL_Surface * image ;
00939
00940 try
00941 {
00942
00943
00944 Ceylan::System::File & imageFile = File::Open( filename ) ;
00945
00946 image = IMG_LoadTyped_RW( & Utils::createDataStreamFrom( imageFile ),
00947 true,
00948 const_cast<char *>( BMPTag.c_str() ) ) ;
00949
00950 }
00951 catch( const Ceylan::Exception & e )
00952 {
00953
00954 throw ImageException( "Image::LoadBMP failed: unable to load from '"
00955 + filename + "': " + e.toString() ) ;
00956
00957 }
00958
00959 if ( image == 0 )
00960 throw ImageException( "Unable to load BMP image stored in " + filename
00961 + " thanks to IMG_LoadTyped_RW: " + string( IMG_GetError() ) ) ;
00962
00963
00964
00965
00966
00967
00968
00969 if ( convertToDisplay )
00970 {
00971
00972 if ( ! VideoModule::IsDisplayInitialized() )
00973 throw ImageException(
00974 "Image::LoadBMP called with request to convert surface "
00975 "to display, whereas display not initialized "
00976 "(VideoModule::setMode never called)." ) ;
00977
00978 SDL_Surface * formattedImage ;
00979
00980
00981
00982
00983
00984
00985
00986 if ( convertWithAlpha )
00987 {
00988
00989 formattedImage = SDL_DisplayFormatAlpha( image ) ;
00990
00991 }
00992 else
00993 {
00994
00995 formattedImage = SDL_DisplayFormat( image ) ;
00996
00997 }
00998
00999 SDL_FreeSurface( image ) ;
01000
01001 image = formattedImage ;
01002
01003 }
01004
01005
01006
01007
01008
01009
01010
01011 if ( blitOnly )
01012 {
01013
01014
01015
01016 #if OSDL_DEBUG
01017
01018 if ( ! targetSurface.isInternalSurfaceAvailable() )
01019 throw ImageException( "Image::LoadBMP: trying to blit image "
01020 "whereas target SDL_surface pointer is null" ) ;
01021
01022 #endif // OSDL_DEBUG
01023
01024
01025 #if OSDL_DEBUG
01026
01027
01028
01029 if ( targetSurface.isLocked() )
01030 throw ImageException( "Image::LoadBMP: trying to blit an image "
01031 "whereas target surface is locked" ) ;
01032
01033 #endif // OSDL_DEBUG
01034
01035 int result = SDL_BlitSurface( image, 0,
01036 & targetSurface.getSDLSurface(), 0 ) ;
01037
01038 if ( result == -1)
01039 throw ImageException( "Image::LoadBMP: error in blit: "
01040 + Utils::getBackendLastError() ) ;
01041
01042 if ( result == -2 )
01043 throw ImageException(
01044 "Image::LoadBMP: video memory was lost during blit." ) ;
01045
01046
01047
01048
01049
01050
01051
01052 SDL_FreeSurface( image ) ;
01053
01054 }
01055 else
01056 {
01057
01058
01059
01060
01061
01062
01063
01064
01065
01066
01067 targetSurface.setSDLSurface( * image ) ;
01068 }
01069
01070
01071
01072
01073
01074
01075
01076
01077
01078
01079
01080 #else // OSDL_USES_SDL_IMAGE
01081
01082 throw ImageException( "Image::LoadBMP failed: "
01083 "no SDL_image support available" ) ;
01084
01085 #endif // OSDL_USES_SDL_IMAGE
01086
01087 }
01088
01089
01090
01091 void Image::LoadGIF( Surface & targetSurface, const std::string & filename,
01092 bool blitOnly, bool convertToDisplay, bool convertWithAlpha )
01093 {
01094
01095 #if OSDL_USES_SDL_IMAGE
01096
01097 if ( ! File::Exists( filename ) )
01098 throw ImageException( "Unable to load GIF file "
01099 + filename + ": file not found." ) ;
01100
01101 SDL_Surface * image ;
01102
01103 try
01104 {
01105
01106
01107 Ceylan::System::File & imageFile = File::Open( filename ) ;
01108
01109 image = IMG_LoadTyped_RW( & Utils::createDataStreamFrom( imageFile ),
01110 true,
01111 const_cast<char *>( GIFTag.c_str() ) ) ;
01112
01113 }
01114 catch( const Ceylan::Exception & e )
01115 {
01116
01117 throw ImageException( "Image::LoadGIF failed: unable to load from '"
01118 + filename + "': " + e.toString() ) ;
01119
01120 }
01121
01122 if ( image == 0 )
01123 throw ImageException( "Unable to load GIF image stored in " + filename
01124 + " thanks to IMG_LoadTyped_RW: " + string( IMG_GetError() ) ) ;
01125
01126
01127
01128
01129
01130
01131
01132 if ( convertToDisplay )
01133 {
01134
01135 if ( ! VideoModule::IsDisplayInitialized() )
01136 throw ImageException(
01137 "Image::LoadGIF called with request to convert surface "
01138 "to display, whereas display not initialized "
01139 "(VideoModule::setMode never called)." ) ;
01140
01141 SDL_Surface * formattedImage ;
01142
01143
01144
01145
01146
01147
01148
01149 if ( convertWithAlpha )
01150 {
01151
01152 formattedImage = SDL_DisplayFormatAlpha( image ) ;
01153
01154 }
01155 else
01156 {
01157
01158 formattedImage = SDL_DisplayFormat( image ) ;
01159
01160 }
01161
01162 SDL_FreeSurface( image ) ;
01163
01164 image = formattedImage ;
01165
01166 }
01167
01168
01169
01170
01171
01172
01173
01174 if ( blitOnly )
01175 {
01176
01177
01178 #if OSDL_DEBUG
01179
01180 if ( ! targetSurface.isInternalSurfaceAvailable() )
01181 throw ImageException( "Image::LoadGIF: trying to blit image "
01182 "whereas target SDL_surface pointer is null" ) ;
01183
01184 #endif // OSDL_DEBUG
01185
01186
01187 #if OSDL_DEBUG
01188
01189
01190
01191 if ( targetSurface.isLocked() )
01192 throw ImageException( "Image::LoadGIF: trying to blit an image "
01193 "whereas target surface is locked" ) ;
01194
01195 #endif // OSDL_DEBUG
01196
01197 int result = SDL_BlitSurface( image, 0,
01198 & targetSurface.getSDLSurface(), 0 ) ;
01199
01200 if ( result == -1)
01201 throw ImageException( "Image::LoadGIF: error in blit: "
01202 + Utils::getBackendLastError() ) ;
01203
01204 if ( result == -2 )
01205 throw ImageException(
01206 "Image::LoadGIF: video memory was lost during blit." ) ;
01207
01208
01209
01210
01211
01212
01213
01214 SDL_FreeSurface( image ) ;
01215
01216 }
01217 else
01218 {
01219
01220
01221
01222
01223
01224
01225
01226
01227
01228
01229 targetSurface.setSDLSurface( * image ) ;
01230 }
01231
01232
01233
01234
01235
01236
01237
01238
01239
01240
01241
01242
01243 #else // OSDL_USES_SDL_IMAGE
01244
01245 throw ImageException( "Image::LoadGIF failed: "
01246 "no SDL_image support available" ) ;
01247
01248 #endif // OSDL_USES_SDL_IMAGE
01249
01250 }
01251
01252
01253
01254 void Image::LoadLBM( Surface & targetSurface, const std::string & filename,
01255 bool blitOnly, bool convertToDisplay, bool convertWithAlpha )
01256 {
01257
01258 #if OSDL_USES_SDL_IMAGE
01259
01260 if ( ! File::Exists( filename ) )
01261 throw ImageException( "Unable to load LBM file "
01262 + filename + ": file not found." ) ;
01263
01264 SDL_Surface * image ;
01265
01266 try
01267 {
01268
01269
01270 Ceylan::System::File & imageFile = File::Open( filename ) ;
01271
01272 image = IMG_LoadTyped_RW( & Utils::createDataStreamFrom( imageFile ),
01273 true,
01274 const_cast<char *>( LBMTag.c_str() ) ) ;
01275
01276 }
01277 catch( const Ceylan::Exception & e )
01278 {
01279
01280 throw ImageException( "Image::LoadLBM failed: unable to load from '"
01281 + filename + "': " + e.toString() ) ;
01282
01283 }
01284
01285 if ( image == 0 )
01286 throw ImageException( "Unable to load LBM image stored in " + filename
01287 + " thanks to IMG_LoadTyped_RW: " + string( IMG_GetError() ) ) ;
01288
01289
01290
01291
01292
01293
01294
01295
01296 if ( convertToDisplay )
01297 {
01298
01299 if ( ! VideoModule::IsDisplayInitialized() )
01300 throw ImageException(
01301 "Image::LoadLBM called with request to convert surface "
01302 "to display, whereas display not initialized "
01303 "(VideoModule::setMode never called)." ) ;
01304
01305 SDL_Surface * formattedImage ;
01306
01307
01308
01309
01310
01311
01312
01313 if ( convertWithAlpha )
01314 {
01315
01316 formattedImage = SDL_DisplayFormatAlpha( image ) ;
01317
01318 }
01319 else
01320 {
01321
01322 formattedImage = SDL_DisplayFormat( image ) ;
01323
01324 }
01325
01326 SDL_FreeSurface( image ) ;
01327
01328 image = formattedImage ;
01329
01330 }
01331
01332
01333
01334
01335
01336
01337
01338 if ( blitOnly )
01339 {
01340
01341
01342 #if OSDL_DEBUG
01343
01344 if ( ! targetSurface.isInternalSurfaceAvailable() )
01345 throw ImageException( "Image::LoadLBM: trying to blit image "
01346 "whereas target SDL_surface pointer is null" ) ;
01347
01348 #endif // OSDL_DEBUG
01349
01350
01351 #if OSDL_DEBUG
01352
01353
01354
01355 if ( targetSurface.isLocked() )
01356 throw ImageException( "Image::LoadLBM: trying to blit an image "
01357 "whereas target surface is locked" ) ;
01358
01359 #endif // OSDL_DEBUG
01360
01361 int result = SDL_BlitSurface( image, 0,
01362 & targetSurface.getSDLSurface(), 0 ) ;
01363
01364 if ( result == -1)
01365 throw ImageException( "Image::LoadLBM: error in blit: "
01366 + Utils::getBackendLastError() ) ;
01367
01368 if ( result == -2 )
01369 throw ImageException(
01370 "Image::LoadLBM: video memory was lost during blit." ) ;
01371
01372
01373
01374
01375
01376
01377
01378 SDL_FreeSurface( image ) ;
01379
01380 }
01381 else
01382 {
01383
01384
01385
01386
01387
01388
01389
01390
01391
01392
01393
01394 targetSurface.setSDLSurface( * image ) ;
01395 }
01396
01397
01398
01399
01400
01401
01402
01403
01404
01405
01406
01407
01408 #else // OSDL_USES_SDL_IMAGE
01409
01410 throw ImageException( "Image::LoadLBM failed: "
01411 "no SDL_image support available" ) ;
01412
01413 #endif // OSDL_USES_SDL_IMAGE
01414
01415 }
01416
01417
01418
01419 void Image::LoadPCX( Surface & targetSurface, const std::string & filename,
01420 bool blitOnly, bool convertToDisplay, bool convertWithAlpha )
01421 {
01422
01423 #if OSDL_USES_SDL_IMAGE
01424
01425 if ( ! File::Exists( filename ) )
01426 throw ImageException( "Unable to load PCX file "
01427 + filename + ": file not found." ) ;
01428
01429 SDL_Surface * image ;
01430
01431 try
01432 {
01433
01434
01435 Ceylan::System::File & imageFile = File::Open( filename ) ;
01436
01437 image = IMG_LoadTyped_RW( & Utils::createDataStreamFrom( imageFile ),
01438 true,
01439 const_cast<char *>( PCXTag.c_str() ) ) ;
01440
01441 }
01442 catch( const Ceylan::Exception & e )
01443 {
01444
01445 throw ImageException( "Image::LoadPCX failed: unable to load from '"
01446 + filename + "': " + e.toString() ) ;
01447
01448 }
01449
01450 if ( image == 0 )
01451 throw ImageException( "Unable to load PCX image stored in " + filename
01452 + " thanks to IMG_LoadTyped_RW: " + string( IMG_GetError() ) ) ;
01453
01454
01455
01456
01457
01458
01459
01460
01461 if ( convertToDisplay )
01462 {
01463
01464
01465 if ( ! VideoModule::IsDisplayInitialized() )
01466 throw ImageException(
01467 "Image::LoadPCX called with request to convert surface "
01468 "to display, whereas display not initialized "
01469 "(VideoModule::setMode never called)." ) ;
01470
01471 SDL_Surface * formattedImage ;
01472
01473
01474
01475
01476
01477
01478
01479 if ( convertWithAlpha )
01480 {
01481
01482 formattedImage = SDL_DisplayFormatAlpha( image ) ;
01483
01484 }
01485 else
01486 {
01487
01488 formattedImage = SDL_DisplayFormat( image ) ;
01489
01490 }
01491
01492 SDL_FreeSurface( image ) ;
01493
01494 image = formattedImage ;
01495
01496 }
01497
01498
01499
01500
01501
01502
01503
01504 if ( blitOnly )
01505 {
01506
01507
01508 #if OSDL_DEBUG
01509
01510 if ( ! targetSurface.isInternalSurfaceAvailable() )
01511 throw ImageException( "Image::LoadPCX: trying to blit image "
01512 "whereas target SDL_surface pointer is null" ) ;
01513
01514 #endif // OSDL_DEBUG
01515
01516
01517 #if OSDL_DEBUG
01518
01519
01520
01521 if ( targetSurface.isLocked() )
01522 throw ImageException( "Image::LoadPCX: trying to blit an image "
01523 "whereas target surface is locked" ) ;
01524
01525 #endif // OSDL_DEBUG
01526
01527 int result = SDL_BlitSurface( image, 0,
01528 & targetSurface.getSDLSurface(), 0 ) ;
01529
01530 if ( result == -1)
01531 throw ImageException( "Image::LoadPCX: error in blit: "
01532 + Utils::getBackendLastError() ) ;
01533
01534 if ( result == -2 )
01535 throw ImageException(
01536 "Image::LoadPCX: video memory was lost during blit." ) ;
01537
01538
01539
01540
01541
01542
01543
01544 SDL_FreeSurface( image ) ;
01545
01546 }
01547 else
01548 {
01549
01550
01551
01552
01553
01554
01555
01556
01557
01558
01559
01560 targetSurface.setSDLSurface( * image ) ;
01561 }
01562
01563
01564
01565
01566
01567
01568
01569
01570
01571
01572
01573 #else // OSDL_USES_SDL_IMAGE
01574
01575 throw ImageException( "Image::LoadPCX failed: "
01576 "no SDL_image support available" ) ;
01577
01578 #endif // OSDL_USES_SDL_IMAGE
01579
01580 }
01581
01582
01583
01584 void Image::LoadPNM( Surface & targetSurface, const std::string & filename,
01585 bool blitOnly, bool convertToDisplay, bool convertWithAlpha )
01586 {
01587
01588 #if OSDL_USES_SDL_IMAGE
01589
01590 if ( ! File::Exists( filename ) )
01591 throw ImageException( "Unable to load PNM file "
01592 + filename + ": file not found." ) ;
01593
01594 SDL_Surface * image ;
01595
01596 try
01597 {
01598
01599
01600 Ceylan::System::File & imageFile = File::Open( filename ) ;
01601
01602 image = IMG_LoadTyped_RW( & Utils::createDataStreamFrom( imageFile ),
01603 true,
01604 const_cast<char *>( PNMTag.c_str() ) ) ;
01605
01606 }
01607 catch( const Ceylan::Exception & e )
01608 {
01609
01610 throw ImageException( "Image::LoadPNM failed: unable to load from '"
01611 + filename + "': " + e.toString() ) ;
01612
01613 }
01614
01615 if ( image == 0 )
01616 throw ImageException( "Unable to load PNM image stored in " + filename
01617 + " thanks to IMG_LoadTyped_RW: " + string( IMG_GetError() ) ) ;
01618
01619
01620
01621
01622
01623
01624
01625
01626 if ( convertToDisplay )
01627 {
01628
01629 if ( ! VideoModule::IsDisplayInitialized() )
01630 throw ImageException(
01631 "Image::LoadPNM called with request to convert surface "
01632 "to display, whereas display not initialized "
01633 "(VideoModule::setMode never called)." ) ;
01634
01635 SDL_Surface * formattedImage ;
01636
01637
01638
01639
01640
01641
01642
01643 if ( convertWithAlpha )
01644 {
01645
01646 formattedImage = SDL_DisplayFormatAlpha( image ) ;
01647
01648 }
01649 else
01650 {
01651
01652 formattedImage = SDL_DisplayFormat( image ) ;
01653
01654 }
01655
01656 SDL_FreeSurface( image ) ;
01657
01658 image = formattedImage ;
01659
01660 }
01661
01662
01663
01664
01665
01666
01667
01668 if ( blitOnly )
01669 {
01670
01671
01672 #if OSDL_DEBUG
01673
01674 if ( ! targetSurface.isInternalSurfaceAvailable() )
01675 throw ImageException( "Image::LoadPNM: trying to blit image "
01676 "whereas target SDL_surface pointer is null" ) ;
01677
01678 #endif // OSDL_DEBUG
01679
01680
01681 #if OSDL_DEBUG
01682
01683
01684
01685 if ( targetSurface.isLocked() )
01686 throw ImageException( "Image::LoadPNM: trying to blit an image "
01687 "whereas target surface is locked" ) ;
01688 #endif // OSDL_DEBUG
01689
01690 int result = SDL_BlitSurface( image, 0,
01691 & targetSurface.getSDLSurface(), 0 ) ;
01692
01693 if ( result == -1)
01694 throw ImageException( "Image::LoadPNM: error in blit: "
01695 + Utils::getBackendLastError() ) ;
01696
01697 if ( result == -2 )
01698 throw ImageException(
01699 "Image::LoadPNM: video memory was lost during blit." ) ;
01700
01701
01702
01703
01704
01705
01706
01707 SDL_FreeSurface( image ) ;
01708
01709 }
01710 else
01711 {
01712
01713
01714
01715
01716
01717
01718
01719
01720
01721
01722
01723 targetSurface.setSDLSurface( * image ) ;
01724 }
01725
01726
01727
01728
01729
01730
01731
01732
01733
01734
01735
01736 #else // OSDL_USES_SDL_IMAGE
01737
01738 throw ImageException( "Image::LoadPNM failed: "
01739 "no SDL_image support available" ) ;
01740
01741 #endif // OSDL_USES_SDL_IMAGE
01742
01743 }
01744
01745
01746
01747 void Image::LoadTGA( Surface & targetSurface, const std::string & filename,
01748 bool blitOnly, bool convertToDisplay, bool convertWithAlpha )
01749 {
01750
01751 #if OSDL_USES_SDL_IMAGE
01752
01753 if ( ! File::Exists( filename ) )
01754 throw ImageException( "Unable to load TGA file "
01755 + filename + ": file not found." ) ;
01756
01757 SDL_Surface * image ;
01758
01759 try
01760 {
01761
01762
01763 Ceylan::System::File & imageFile = File::Open( filename ) ;
01764
01765 image = IMG_LoadTyped_RW( & Utils::createDataStreamFrom( imageFile ),
01766 true,
01767 const_cast<char *>( TGATag.c_str() ) ) ;
01768
01769 }
01770 catch( const Ceylan::Exception & e )
01771 {
01772
01773 throw ImageException( "Image::LoadTGA failed: unable to load from '"
01774 + filename + "': " + e.toString() ) ;
01775
01776 }
01777
01778 if ( image == 0 )
01779 throw ImageException( "Unable to load TGA image stored in " + filename
01780 + " thanks to IMG_LoadTyped_RW: " + string( IMG_GetError() ) ) ;
01781
01782
01783
01784
01785
01786
01787
01788
01789 if ( convertToDisplay )
01790 {
01791
01792 if ( ! VideoModule::IsDisplayInitialized() )
01793 throw ImageException(
01794 "Image::LoadTGA called with request to convert surface "
01795 "to display, whereas display not initialized "
01796 "(VideoModule::setMode never called)." ) ;
01797
01798 SDL_Surface * formattedImage ;
01799
01800
01801
01802
01803
01804
01805
01806 if ( convertWithAlpha )
01807 {
01808
01809 formattedImage = SDL_DisplayFormatAlpha( image ) ;
01810
01811 }
01812 else
01813 {
01814
01815 formattedImage = SDL_DisplayFormat( image ) ;
01816
01817 }
01818
01819 SDL_FreeSurface( image ) ;
01820
01821 image = formattedImage ;
01822
01823 }
01824
01825
01826
01827
01828
01829
01830
01831 if ( blitOnly )
01832 {
01833
01834
01835 #if OSDL_DEBUG
01836
01837 if ( ! targetSurface.isInternalSurfaceAvailable() )
01838 throw ImageException( "Image::LoadTGA: trying to blit image "
01839 "whereas target SDL_surface pointer is null" ) ;
01840
01841 #endif // OSDL_DEBUG
01842
01843
01844 #if OSDL_DEBUG
01845
01846
01847
01848 if ( targetSurface.isLocked() )
01849 throw ImageException( "Image::LoadTGA: trying to blit an image "
01850 "whereas target surface is locked" ) ;
01851
01852 #endif // OSDL_DEBUG
01853
01854 int result = SDL_BlitSurface( image, 0,
01855 & targetSurface.getSDLSurface(), 0 ) ;
01856
01857 if ( result == -1)
01858 throw ImageException( "Image::LoadTGA: error in blit: "
01859 + Utils::getBackendLastError() ) ;
01860
01861 if ( result == -2 )
01862 throw ImageException(
01863 "Image::LoadTGA: video memory was lost during blit." ) ;
01864
01865
01866
01867
01868
01869
01870
01871 SDL_FreeSurface( image ) ;
01872
01873 }
01874 else
01875 {
01876
01877
01878
01879
01880
01881
01882
01883
01884
01885
01886
01887 targetSurface.setSDLSurface( * image ) ;
01888 }
01889
01890
01891
01892
01893
01894
01895
01896
01897
01898
01899
01900
01901 #else // OSDL_USES_SDL_IMAGE
01902
01903 throw ImageException( "Image::LoadTGA failed: "
01904 "no SDL_image support available" ) ;
01905
01906 #endif // OSDL_USES_SDL_IMAGE
01907
01908 }
01909
01910
01911
01912 void Image::LoadXPM( Surface & targetSurface, const std::string & filename,
01913 bool blitOnly, bool convertToDisplay, bool convertWithAlpha )
01914 {
01915
01916 #if OSDL_USES_SDL_IMAGE
01917
01918 if ( ! File::Exists( filename ) )
01919 throw ImageException( "Unable to load XPM file "
01920 + filename + ": file not found." ) ;
01921
01922 SDL_Surface * image ;
01923
01924 try
01925 {
01926
01927
01928 Ceylan::System::File & imageFile = File::Open( filename ) ;
01929
01930 image = IMG_LoadTyped_RW( & Utils::createDataStreamFrom( imageFile ),
01931 true,
01932 const_cast<char *>( XPMTag.c_str() ) ) ;
01933
01934 }
01935 catch( const Ceylan::Exception & e )
01936 {
01937
01938 throw ImageException( "Image::LoadXPM failed: unable to load from '"
01939 + filename + "': " + e.toString() ) ;
01940
01941 }
01942
01943 if ( image == 0 )
01944 throw ImageException( "Unable to load XPM image stored in " + filename
01945 + " thanks to IMG_LoadTyped_RW: " + string( IMG_GetError() ) ) ;
01946
01947
01948
01949
01950
01951
01952
01953
01954 if ( convertToDisplay )
01955 {
01956
01957 if ( ! VideoModule::IsDisplayInitialized() )
01958 throw ImageException(
01959 "Image::LoadXPM called with request to convert surface "
01960 "to display, whereas display not initialized "
01961 "(VideoModule::setMode never called)." ) ;
01962
01963 SDL_Surface * formattedImage ;
01964
01965
01966
01967
01968
01969
01970
01971 if ( convertWithAlpha )
01972 {
01973
01974 formattedImage = SDL_DisplayFormatAlpha( image ) ;
01975
01976 }
01977 else
01978 {
01979
01980 formattedImage = SDL_DisplayFormat( image ) ;
01981
01982 }
01983
01984 SDL_FreeSurface( image ) ;
01985
01986 image = formattedImage ;
01987
01988 }
01989
01990
01991
01992
01993
01994
01995
01996 if ( blitOnly )
01997 {
01998
01999
02000 #if OSDL_DEBUG
02001
02002 if ( ! targetSurface.isInternalSurfaceAvailable() )
02003 throw ImageException( "Image::LoadXPM: trying to blit image "
02004 "whereas target SDL_surface pointer is null" ) ;
02005
02006 #endif // OSDL_DEBUG
02007
02008
02009 #if OSDL_DEBUG
02010
02011
02012
02013 if ( targetSurface.isLocked() )
02014 throw ImageException( "Image::LoadXPM: trying to blit an image "
02015 "whereas target surface is locked" ) ;
02016
02017 #endif // OSDL_DEBUG
02018
02019 int result = SDL_BlitSurface( image, 0,
02020 & targetSurface.getSDLSurface(), 0 ) ;
02021
02022 if ( result == -1)
02023 throw ImageException(
02024 "Image::LoadXPM: error in blit: "
02025 + Utils::getBackendLastError() ) ;
02026
02027 if ( result == -2 )
02028 throw ImageException(
02029 "Image::LoadXPM: video memory was lost during blit." ) ;
02030
02031
02032
02033
02034
02035
02036
02037 SDL_FreeSurface( image ) ;
02038
02039 }
02040 else
02041 {
02042
02043
02044
02045
02046
02047
02048
02049
02050
02051
02052
02053 targetSurface.setSDLSurface( * image ) ;
02054 }
02055
02056
02057
02058
02059
02060
02061
02062
02063
02064
02065
02066
02067 #else // OSDL_USES_SDL_IMAGE
02068
02069 throw ImageException( "Image::LoadXPM failed: "
02070 "no SDL_image support available" ) ;
02071
02072 #endif // OSDL_USES_SDL_IMAGE
02073
02074 }
02075
02076
02077
02078 void Image::SavePNG( Surface & targetSurface, const std::string & filename,
02079 bool overwrite )
02080 {
02081
02082 #if OSDL_USES_LIBPNG
02083
02084
02085
02086 if ( ! overwrite && Ceylan::System::File::Exists( filename ) )
02087 throw TwoDimensional::ImageException(
02088 "Surface::SavePNG: target file '" + filename
02089 + "' already exists, and overwrite mode is off." ) ;
02090
02091 png_structp png_ptr ;
02092 png_infop info_ptr ;
02093
02094 png_ptr = ::png_create_write_struct( PNG_LIBPNG_VER_STRING, 0, 0, 0 ) ;
02095
02096 if ( png_ptr == 0 )
02097 {
02098
02099
02100 ::png_destroy_write_struct( & png_ptr, (png_infopp) 0 ) ;
02101 throw TwoDimensional::ImageException(
02102 "Surface::SavePNG: unable to save image '"
02103 + filename + "' (step 1)" ) ;
02104 }
02105
02106
02107 info_ptr = ::png_create_info_struct( png_ptr ) ;
02108
02109 if ( info_ptr == 0 )
02110 {
02111 ::png_destroy_write_struct( & png_ptr, (png_infopp) 0 ) ;
02112 throw TwoDimensional::ImageException(
02113 "Surface::SavePNG: unable to save image '"
02114 + filename + "' (step 2)" ) ;
02115 }
02116
02117
02118 if ( ::setjmp( png_jmpbuf( png_ptr ) ) )
02119 {
02120 ::png_destroy_write_struct( & png_ptr, (png_infopp) 0 ) ;
02121 throw TwoDimensional::ImageException(
02122 "Surface::SavePNG: unable to save image '"
02123 + filename + "' (step 3)" ) ;
02124 }
02125
02126
02127
02128
02129
02130
02131
02132
02133
02134
02135
02136
02137
02138
02139
02140
02141 FILE * outputFile = ::fopen( filename.c_str(), "wb" ) ;
02142
02143 if ( outputFile == 0 )
02144 {
02145
02146 ::png_destroy_write_struct( & png_ptr, (png_infopp) 0 ) ;
02147
02148 throw TwoDimensional::ImageException(
02149 "Surface::SavePNG: unable to save image '"
02150 + filename + "' (step 4): " + Ceylan::System::explainError() ) ;
02151 }
02152
02153 ::png_init_io( png_ptr, outputFile ) ;
02154
02155
02156
02157
02158
02159
02160
02161
02162
02163
02164
02165 ::png_set_IHDR( png_ptr, info_ptr, targetSurface.getWidth(),
02166 targetSurface.getHeight(), 8,
02167 PNG_COLOR_TYPE_RGB,
02168 PNG_INTERLACE_NONE,
02169 PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE ) ;
02170
02171
02172
02173
02174
02175
02176
02177
02178
02179
02180
02181
02182
02183
02184
02185
02186
02187
02188
02189
02190
02191
02192
02193
02194
02195
02196
02197
02198
02199
02200
02201
02202
02203
02204
02205
02206
02207
02208
02209
02210
02211
02212
02213
02214
02215
02216
02217
02218
02219
02220
02221
02222
02223 ::png_write_info( png_ptr, info_ptr ) ;
02224
02225
02226
02227 targetSurface.lock() ;
02228
02229 unsigned char ** png_rows =
02230 new unsigned char * [ targetSurface.getHeight() ] ;
02231
02232 for ( Coordinate y = 0; y < targetSurface.getHeight(); y++ )
02233 {
02234
02235 png_rows[ y ] = new unsigned char[ 3 * targetSurface.getWidth() ] ;
02236
02237 ColorDefinition readDef ;
02238
02239 for ( Coordinate x = 0; x < targetSurface.getWidth(); x++ )
02240 {
02241
02242 readDef = targetSurface.getColorDefinitionAt( x, y ) ;
02243
02244
02245
02246
02247
02248 png_rows[ y ][ x * 3 + 0 ] = readDef.r ;
02249 png_rows[ y ][ x * 3 + 1 ] = readDef.g ;
02250 png_rows[ y ][ x * 3 + 2 ] = readDef.b ;
02251 }
02252 }
02253
02254 targetSurface.unlock() ;
02255
02256 ::png_write_image( png_ptr, png_rows ) ;
02257
02258 for ( Coordinate y = 0; y < targetSurface.getHeight(); y++ )
02259 delete [] png_rows[ y ] ;
02260
02261 delete [] png_rows ;
02262
02263 ::png_write_end( png_ptr, 0 ) ;
02264
02265 ::png_destroy_write_struct( & png_ptr, & info_ptr ) ;
02266
02267 ::fclose( outputFile ) ;
02268
02269 #else // OSDL_USES_LIBPNG
02270
02271 throw ImageException( "Image::SavePNG failed: "
02272 "no libpng support available" ) ;
02273
02274 #endif // OSDL_USES_LIBPNG
02275
02276 }
02277
02278
02279
02280 void Image::SaveBMP( Surface & targetSurface, const std::string & filename,
02281 bool overwrite )
02282 {
02283
02284 #if OSDL_USES_SDL
02285
02286 if ( ! overwrite && Ceylan::System::File::Exists( filename ) )
02287 throw TwoDimensional::ImageException(
02288 "Surface::SaveBMP: target file '" + filename
02289 + "' already exists, and overwrite mode is off." ) ;
02290
02291 if ( SDL_SaveBMP( & targetSurface.getSDLSurface(), filename.c_str() ) != 0 )
02292 throw TwoDimensional::ImageException(
02293 "Surface::SaveBMP: error while saving BMP file '"
02294 + filename + "': " + OSDL::Utils::getBackendLastError() ) ;
02295
02296 #else // OSDL_USES_SDL
02297
02298 throw ImageException( "Image::SaveBMP failed: "
02299 "no SDL support available" ) ;
02300
02301 #endif // OSDL_USES_SDL
02302
02303 }