00001 #include "OSDLImage.h"
00002
00003 #include "OSDLVideo.h"
00004 #include "OSDLUtils.h"
00005 #include "OSDLSurface.h"
00006 #include "OSDLPixel.h"
00007
00008
00009 #include "SDL_image.h"
00010
00011 #include "png.h"
00012
00013
00014 #ifdef OSDL_USES_CONFIG_H
00015 #include <OSDLConfig.h>
00016 #endif // OSDL_USES_CONFIG_H
00017
00018
00019 using std::string ;
00020
00021 using namespace Ceylan::Log ;
00022 using namespace Ceylan::System ;
00023
00024 using namespace OSDL::Video ;
00025 using namespace OSDL::Video::TwoDimensional ;
00026
00027
00029
00030 const string Image::JPGTag = "JPG" ;
00031 const string Image::PNGTag = "PNG" ;
00032
00033
00035
00036 const string Image::BMPTag = "BMP" ;
00037 const string Image::GIFTag = "GIF" ;
00038 const string Image::LBMTag = "LBM" ;
00039 const string Image::PCXTag = "PCX" ;
00040 const string Image::PNMTag = "PNM" ;
00041 const string Image::TGATag = "TGA" ;
00042 const string Image::XPMTag = "XPM" ;
00043
00044
00045
00046 ImageException::ImageException( const std::string & reason ) throw() :
00047 VideoException( reason )
00048 {
00049
00050 }
00051
00052
00053 ImageException::~ImageException() throw()
00054 {
00055
00056 }
00057
00058
00059
00065 Image::Image( const string & filename ) throw( ImageException )
00066 {
00067
00068 }
00069
00070
00071 Image::~Image() throw()
00072 {
00073
00074 }
00075
00076
00077 Surface & Image::LoadIcon( const string & filename,
00078 Pixels::ColorElement ** mask ) throw( ImageException )
00079 {
00080
00081
00082
00083 #if OSDL_DEBUG_IMAGE
00084 LogPlug::debug( "Loading icon." ) ;
00085 #endif // OSDL_DEBUG_IMAGE
00086
00087
00088
00089
00090 Surface & iconSurface = Surface::LoadImage( filename,
00091 false, false ) ;
00092
00093
00094 #if OSDL_DEBUG_IMAGE
00095 LogPlug::debug( "Icon loaded." ) ;
00096
00097 LogPlug::debug( "Displaying icon informations : "
00098 + iconSurface.toString() ) ;
00099 #endif // OSDL_DEBUG_IMAGE
00100
00101 if ( iconSurface.getPixelFormat().palette == 0 )
00102 {
00103
00104 delete & iconSurface ;
00105 throw ImageException( "Image::LoadIcon : image " + filename
00106 + " does not seem to have a palette as it should." ) ;
00107
00108 }
00109
00110
00111 iconSurface.setColorKey( Surface::ColorkeyBlit,
00112 * ( (Pixels::ColorElement *) iconSurface.getPixels() ) ) ;
00113
00114 ColorElement * pixels = (ColorElement *) iconSurface.getPixels() ;
00115
00116 #if OSDL_DEBUG_IMAGE
00117
00118 LogPlug::debug( "Image::LoadIcon : index of upper left pixel is "
00119 + Ceylan::toString( static_cast<unsigned short>( *pixels ) ) ) ;
00120
00121 LogPlug::debug( "Image::LoadIcon : transparent pixel is : "
00122 + Pixels::toString(
00123 iconSurface.getPixelFormat().palette->colors[*pixels] ) ) ;
00124
00125
00126 LogPlug::debug(
00127 "Creating image mask (one bit per image pixel, rounded up)" ) ;
00128
00129 #endif // OSDL_DEBUG_IMAGE
00130
00131 int maskLen = ( iconSurface.getWidth() * iconSurface.getHeight() + 7 ) / 8 ;
00132 ColorElement * constructedMask = new ColorElement[ maskLen ] ;
00133
00134 if ( constructedMask == 0 )
00135 {
00136 delete & iconSurface ;
00137 throw ImageException( "Image::LoadIcon : not enough memory." ) ;
00138 }
00139
00140 ::memset( constructedMask, 0, maskLen ) ;
00141
00142 int paletteIndex ;
00143 int maskIndex ;
00144
00145
00146 for ( Coordinate i = 0; i < iconSurface.getHeight(); i++ )
00147 {
00148
00149
00150
00151 for ( Coordinate j = 0; j < iconSurface.getWidth(); j++ )
00152 {
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163 paletteIndex = i * iconSurface.getPitch() + j ;
00164 maskIndex = i * iconSurface.getWidth() + j ;
00165
00166
00167
00168
00169
00170
00171 if ( pixels[ paletteIndex ] != *pixels )
00172 constructedMask[ maskIndex >>3 ] |=
00173 1 << ( 7 - ( maskIndex & 7) ) ;
00174 }
00175
00176 }
00177
00178 #if OSDL_DEBUG_IMAGE
00179 LogPlug::debug( "Icon scanned." ) ;
00180 #endif // OSDL_DEBUG_IMAGE
00181
00182 *mask = constructedMask ;
00183
00184 #if OSDL_DEBUG_IMAGE
00185 LogPlug::debug( "Icon fully loaded." ) ;
00186 #endif // OSDL_DEBUG_IMAGE
00187
00188 return iconSurface ;
00189
00190 }
00191
00192
00193
00194 void Image::Load( Surface & targetSurface, const std::string & filename,
00195 bool blitOnly, bool convertToDisplay, bool convertWithAlpha )
00196 throw( ImageException )
00197 {
00198
00199 #if OSDL_DEBUG_IMAGE
00200 LogPlug::debug( "Image::Load : loading image from " + filename ) ;
00201 #endif // OSDL_DEBUG_IMAGE
00202
00203 if ( ! File::Exists( filename ) )
00204 throw ImageException( "Unable to load JPG file " + filename
00205 + " : file not found." ) ;
00206
00207 SDL_Surface * image = IMG_Load( filename.c_str() ) ;
00208
00209 if ( image == 0 )
00210 throw ImageException( "Unable to load image stored in " + filename
00211 + " thanks to IMG_Load : "
00212 + string( IMG_GetError() ) ) ;
00213
00214 #if OSDL_DEBUG_IMAGE
00215 LogPlug::debug( "Image loaded." ) ;
00216 #endif // OSDL_DEBUG_IMAGE
00217
00218
00219
00220
00221
00222
00223
00224 if ( convertToDisplay )
00225 {
00226
00227 if ( ! VideoModule::IsDisplayInitialized() )
00228 throw ImageException(
00229 "Image::Load called with request to convert surface "
00230 "to display, whereas display not initialized "
00231 "(VideoModule::setMode never called)." ) ;
00232
00233 SDL_Surface * formattedImage ;
00234
00235
00236
00237
00238
00239
00240
00241 if ( convertWithAlpha )
00242 {
00243
00244 #if OSDL_DEBUG_IMAGE
00245 LogPlug::debug(
00246 "Converting image to display format, with alpha." ) ;
00247 #endif // OSDL_DEBUG_IMAGE
00248
00249 formattedImage = SDL_DisplayFormatAlpha( image ) ;
00250
00251 }
00252 else
00253 {
00254
00255 #if OSDL_DEBUG_IMAGE
00256 LogPlug::debug( "Converting image to display format, no alpha." ) ;
00257 #endif // OSDL_DEBUG_IMAGE
00258
00259 formattedImage = SDL_DisplayFormat( image ) ;
00260
00261 }
00262
00263 SDL_FreeSurface( image ) ;
00264
00265 image = formattedImage ;
00266
00267 if ( image == 0 )
00268 throw ImageException(
00269 "Unable to convert to display the image loaded from "
00270 + filename + "." ) ;
00271
00272 }
00273
00274
00275
00276
00277
00278
00279
00280 if ( blitOnly )
00281 {
00282
00283
00284 #if OSDL_DEBUG_IMAGE
00285 LogPlug::debug( "Blitting loaded image to already existing surface." ) ;
00286 #endif // OSDL_DEBUG_IMAGE
00287
00288 #if OSDL_DEBUG
00289
00290 if ( ! targetSurface.isInternalSurfaceAvailable() )
00291 throw ImageException( "Image::Load : trying to blit image "
00292 "whereas target SDL_surface pointer is null" ) ;
00293
00294 #endif // OSDL_DEBUG
00295
00296
00297 #if OSDL_DEBUG
00298
00299
00300
00301 if ( targetSurface.isLocked() )
00302 throw ImageException( "Image::Load : trying to blit an image "
00303 "whereas target surface is locked" ) ;
00304
00305 #endif // OSDL_DEBUG
00306
00307 int result = SDL_BlitSurface( image, 0,
00308 & targetSurface.getSDLSurface(), 0 ) ;
00309
00310 if ( result == -1)
00311 throw ImageException( "Image::Load : error in blit : "
00312 + Utils::getBackendLastError() ) ;
00313
00314 if ( result == -2 )
00315 throw ImageException(
00316 "Image::Load : video memory was lost during blit." ) ;
00317
00318
00319
00320
00321
00322
00323
00324 SDL_FreeSurface( image ) ;
00325
00326 }
00327 else
00328 {
00329
00330 #if OSDL_DEBUG_IMAGE
00331 LogPlug::debug( "Replacing already existing image by loaded one." ) ;
00332 #endif // OSDL_DEBUG
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343 targetSurface.setSDLSurface( * image ) ;
00344
00345 }
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358 #if OSDL_DEBUG_IMAGE
00359 LogPlug::debug( "Image loaded." ) ;
00360 #endif // OSDL_DEBUG
00361
00362 }
00363
00364
00365
00366 void Image::LoadJPG( Surface & targetSurface, const std::string & filename,
00367 bool blitOnly, bool convertToDisplay, bool convertWithAlpha )
00368 throw( ImageException )
00369 {
00370
00371 if ( ! File::Exists( filename ) )
00372 throw ImageException( "Unable to load JPG file "
00373 + filename + " : file not found." ) ;
00374
00375 SDL_Surface * image ;
00376
00377 image = IMG_LoadTyped_RW( SDL_RWFromFile( filename.c_str(), "rb" ),
00378 1, const_cast<char *>( JPGTag.c_str() ) ) ;
00379
00380 if ( image == 0 )
00381 throw ImageException( "Unable to load JPG image stored in " + filename
00382 + " thanks to IMG_Load_RW : "
00383 + string( IMG_GetError() ) ) ;
00384
00385
00386
00387
00388
00389
00390
00391
00392 if ( convertToDisplay )
00393 {
00394
00395 if ( ! VideoModule::IsDisplayInitialized() )
00396 throw ImageException(
00397 "Image::LoadJPG called with request to convert surface "
00398 "to display, whereas display not initialized "
00399 "(VideoModule::setMode never called)." ) ;
00400
00401 SDL_Surface * formattedImage ;
00402
00403
00404
00405
00406
00407
00408
00409 if ( convertWithAlpha )
00410 {
00411
00412 formattedImage = SDL_DisplayFormatAlpha( image ) ;
00413
00414 }
00415 else
00416 {
00417
00418 formattedImage = SDL_DisplayFormat( image ) ;
00419
00420 }
00421
00422 SDL_FreeSurface( image ) ;
00423
00424 image = formattedImage ;
00425
00426 }
00427
00428
00429
00430
00431
00432
00433
00434 if ( blitOnly )
00435 {
00436
00437
00438
00439 #if OSDL_DEBUG
00440
00441 if ( ! targetSurface.isInternalSurfaceAvailable() )
00442 throw ImageException( "Image::LoadJPG : trying to blit image "
00443 "whereas target SDL_surface pointer is null" ) ;
00444
00445 #endif // OSDL_DEBUG
00446
00447
00448 #if OSDL_DEBUG
00449
00450
00451
00452 if ( targetSurface.isLocked() )
00453 throw ImageException( "Image::LoadJPG : trying to blit an image "
00454 "whereas target surface is locked" ) ;
00455
00456 #endif // OSDL_DEBUG
00457
00458
00459 int result = SDL_BlitSurface( image, 0,
00460 & targetSurface.getSDLSurface(), 0 ) ;
00461
00462 if ( result == -1)
00463 throw ImageException( "Image::LoadJPG : error in blit : "
00464 + Utils::getBackendLastError() ) ;
00465
00466 if ( result == -2 )
00467 throw ImageException(
00468 "Image::LoadJPG : video memory was lost during blit." ) ;
00469
00470
00471
00472
00473
00474
00475
00476
00477 SDL_FreeSurface( image ) ;
00478
00479 }
00480 else
00481 {
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491 targetSurface.setSDLSurface( * image ) ;
00492 }
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505 }
00506
00507
00508
00509 void Image::LoadPNG( Surface & targetSurface, const std::string & filename,
00510 bool blitOnly, bool convertToDisplay, bool convertWithAlpha )
00511 throw( ImageException )
00512 {
00513
00514 if ( ! File::Exists( filename ) )
00515 throw ImageException( "Unable to load PNG file "
00516 + filename + " : file not found." ) ;
00517
00518 SDL_Surface * image ;
00519
00520 image = IMG_LoadTyped_RW( SDL_RWFromFile( filename.c_str(), "rb" ),
00521 1, const_cast<char *>( PNGTag.c_str() ) ) ;
00522
00523 if ( image == 0 )
00524 throw ImageException( "Unable to load PNG image stored in "
00525 + filename + " thanks to IMG_Load_RW : "
00526 + string( IMG_GetError() ) ) ;
00527
00528
00529
00530
00531
00532
00533
00534
00535 if ( convertToDisplay )
00536 {
00537
00538 if ( ! VideoModule::IsDisplayInitialized() )
00539 throw ImageException(
00540 "Image::LoadPNG called with request to convert surface "
00541 "to display, whereas display not initialized "
00542 "(VideoModule::setMode never called)." ) ;
00543
00544 SDL_Surface * formattedImage ;
00545
00546
00547
00548
00549
00550
00551
00552 if ( convertWithAlpha )
00553 {
00554
00555 formattedImage = SDL_DisplayFormatAlpha( image ) ;
00556
00557 }
00558 else
00559 {
00560
00561 formattedImage = SDL_DisplayFormat( image ) ;
00562
00563 }
00564
00565 SDL_FreeSurface( image ) ;
00566
00567 image = formattedImage ;
00568
00569 }
00570
00571
00572
00573
00574
00575
00576
00577 if ( blitOnly )
00578 {
00579
00580
00581
00582 #if OSDL_DEBUG
00583
00584 if ( ! targetSurface.isInternalSurfaceAvailable() )
00585 throw ImageException( "Image::LoadPNG : trying to blit image "
00586 "whereas target SDL_surface pointer is null" ) ;
00587
00588 #endif // OSDL_DEBUG
00589
00590
00591 #if OSDL_DEBUG
00592
00593
00594
00595 if ( targetSurface.isLocked() )
00596 throw ImageException( "Image::LoadPNG : trying to blit an image "
00597 "whereas target surface is locked" ) ;
00598
00599 #endif // OSDL_DEBUG
00600
00601 int result = SDL_BlitSurface( image, 0,
00602 & targetSurface.getSDLSurface(), 0 ) ;
00603
00604 if ( result == -1)
00605 throw ImageException( "Image::LoadPNG : error in blit : "
00606 + Utils::getBackendLastError() ) ;
00607
00608 if ( result == -2 )
00609 throw ImageException(
00610 "Image::LoadPNG : video memory was lost during blit." ) ;
00611
00612
00613
00614
00615
00616
00617
00618 SDL_FreeSurface( image ) ;
00619
00620 }
00621 else
00622 {
00623
00624
00625
00626
00627
00628
00629
00630
00631
00632 targetSurface.setSDLSurface( * image ) ;
00633
00634 }
00635
00636
00637
00638
00639
00640
00641
00642
00643
00644
00645
00646 }
00647
00648
00649 void Image::LoadBMP( Surface & targetSurface, const std::string & filename,
00650 bool blitOnly, bool convertToDisplay, bool convertWithAlpha )
00651 throw( ImageException )
00652 {
00653
00654 if ( ! File::Exists( filename ) )
00655 throw ImageException( "Unable to load BMP file "
00656 + filename + " : file not found." ) ;
00657
00658 SDL_Surface * image ;
00659
00660 image = IMG_LoadTyped_RW( SDL_RWFromFile( filename.c_str(), "rb" ),
00661 1, const_cast<char *>( BMPTag.c_str() ) ) ;
00662
00663 if ( image == 0 )
00664 throw ImageException( "Unable to load BMP image stored in "
00665 + filename
00666 + " thanks to IMG_Load_RW : "
00667 + string( IMG_GetError() ) ) ;
00668
00669
00670
00671
00672
00673
00674
00675
00676 if ( convertToDisplay )
00677 {
00678
00679 if ( ! VideoModule::IsDisplayInitialized() )
00680 throw ImageException(
00681 "Image::LoadBMP called with request to convert surface "
00682 "to display, whereas display not initialized "
00683 "(VideoModule::setMode never called)." ) ;
00684
00685 SDL_Surface * formattedImage ;
00686
00687
00688
00689
00690
00691
00692
00693 if ( convertWithAlpha )
00694 {
00695
00696 formattedImage = SDL_DisplayFormatAlpha( image ) ;
00697
00698 }
00699 else
00700 {
00701
00702 formattedImage = SDL_DisplayFormat( image ) ;
00703
00704 }
00705
00706 SDL_FreeSurface( image ) ;
00707
00708 image = formattedImage ;
00709
00710 }
00711
00712
00713
00714
00715
00716
00717
00718 if ( blitOnly )
00719 {
00720
00721
00722
00723 #if OSDL_DEBUG
00724
00725 if ( ! targetSurface.isInternalSurfaceAvailable() )
00726 throw ImageException( "Image::LoadBMP : trying to blit image "
00727 "whereas target SDL_surface pointer is null" ) ;
00728
00729 #endif // OSDL_DEBUG
00730
00731
00732 #if OSDL_DEBUG
00733
00734
00735
00736 if ( targetSurface.isLocked() )
00737 throw ImageException( "Image::LoadBMP : trying to blit an image "
00738 "whereas target surface is locked" ) ;
00739
00740 #endif // OSDL_DEBUG
00741
00742 int result = SDL_BlitSurface( image, 0,
00743 & targetSurface.getSDLSurface(), 0 ) ;
00744
00745 if ( result == -1)
00746 throw ImageException( "Image::LoadBMP : error in blit : "
00747 + Utils::getBackendLastError() ) ;
00748
00749 if ( result == -2 )
00750 throw ImageException(
00751 "Image::LoadBMP : video memory was lost during blit." ) ;
00752
00753
00754
00755
00756
00757
00758
00759 SDL_FreeSurface( image ) ;
00760
00761 }
00762 else
00763 {
00764
00765
00766
00767
00768
00769
00770
00771
00772
00773
00774 targetSurface.setSDLSurface( * image ) ;
00775 }
00776
00777
00778
00779
00780
00781
00782
00783
00784
00785
00786
00787 }
00788
00789
00790
00791 void Image::LoadGIF( Surface & targetSurface, const std::string & filename,
00792 bool blitOnly, bool convertToDisplay, bool convertWithAlpha )
00793 throw( ImageException )
00794 {
00795
00796 if ( ! File::Exists( filename ) )
00797 throw ImageException( "Unable to load GIF file "
00798 + filename + " : file not found." ) ;
00799
00800 SDL_Surface * image ;
00801
00802 image = IMG_LoadTyped_RW( SDL_RWFromFile( filename.c_str(), "rb" ),
00803 1, const_cast<char *>( GIFTag.c_str() ) ) ;
00804
00805 if ( image == 0 )
00806 throw ImageException( "Unable to load GIF image stored in " + filename
00807 + " thanks to IMG_Load_RW : "
00808 + string( IMG_GetError() ) ) ;
00809
00810
00811
00812
00813
00814
00815
00816
00817 if ( convertToDisplay )
00818 {
00819
00820 if ( ! VideoModule::IsDisplayInitialized() )
00821 throw ImageException(
00822 "Image::LoadGIF called with request to convert surface "
00823 "to display, whereas display not initialized "
00824 "(VideoModule::setMode never called)." ) ;
00825
00826 SDL_Surface * formattedImage ;
00827
00828
00829
00830
00831
00832
00833
00834 if ( convertWithAlpha )
00835 {
00836
00837 formattedImage = SDL_DisplayFormatAlpha( image ) ;
00838
00839 }
00840 else
00841 {
00842
00843 formattedImage = SDL_DisplayFormat( image ) ;
00844
00845 }
00846
00847 SDL_FreeSurface( image ) ;
00848
00849 image = formattedImage ;
00850
00851 }
00852
00853
00854
00855
00856
00857
00858
00859 if ( blitOnly )
00860 {
00861
00862
00863 #if OSDL_DEBUG
00864
00865 if ( ! targetSurface.isInternalSurfaceAvailable() )
00866 throw ImageException( "Image::LoadGIF : trying to blit image "
00867 "whereas target SDL_surface pointer is null" ) ;
00868
00869 #endif // OSDL_DEBUG
00870
00871
00872 #if OSDL_DEBUG
00873
00874
00875
00876 if ( targetSurface.isLocked() )
00877 throw ImageException( "Image::LoadGIF : trying to blit an image "
00878 "whereas target surface is locked" ) ;
00879
00880 #endif // OSDL_DEBUG
00881
00882 int result = SDL_BlitSurface( image, 0,
00883 & targetSurface.getSDLSurface(), 0 ) ;
00884
00885 if ( result == -1)
00886 throw ImageException( "Image::LoadGIF : error in blit : "
00887 + Utils::getBackendLastError() ) ;
00888
00889 if ( result == -2 )
00890 throw ImageException(
00891 "Image::LoadGIF : video memory was lost during blit." ) ;
00892
00893
00894
00895
00896
00897
00898
00899 SDL_FreeSurface( image ) ;
00900
00901 }
00902 else
00903 {
00904
00905
00906
00907
00908
00909
00910
00911
00912
00913
00914 targetSurface.setSDLSurface( * image ) ;
00915 }
00916
00917
00918
00919
00920
00921
00922
00923
00924
00925
00926
00927
00928 }
00929
00930
00931 void Image::LoadLBM( Surface & targetSurface, const std::string & filename,
00932 bool blitOnly, bool convertToDisplay, bool convertWithAlpha )
00933 throw( ImageException )
00934 {
00935
00936 if ( ! File::Exists( filename ) )
00937 throw ImageException( "Unable to load LBM file "
00938 + filename + " : file not found." ) ;
00939
00940 SDL_Surface * image ;
00941
00942 image = IMG_LoadTyped_RW( SDL_RWFromFile( filename.c_str(), "rb" ),
00943 1, const_cast<char *>( LBMTag.c_str() ) ) ;
00944
00945 if ( image == 0 )
00946 throw ImageException( "Unable to load LBM image stored in " + filename
00947 + " thanks to IMG_Load_RW : "
00948 + string( IMG_GetError() ) ) ;
00949
00950
00951
00952
00953
00954
00955
00956
00957 if ( convertToDisplay )
00958 {
00959
00960 if ( ! VideoModule::IsDisplayInitialized() )
00961 throw ImageException(
00962 "Image::LoadLBM called with request to convert surface "
00963 "to display, whereas display not initialized "
00964 "(VideoModule::setMode never called)." ) ;
00965
00966 SDL_Surface * formattedImage ;
00967
00968
00969
00970
00971
00972
00973
00974 if ( convertWithAlpha )
00975 {
00976
00977 formattedImage = SDL_DisplayFormatAlpha( image ) ;
00978
00979 }
00980 else
00981 {
00982
00983 formattedImage = SDL_DisplayFormat( image ) ;
00984
00985 }
00986
00987 SDL_FreeSurface( image ) ;
00988
00989 image = formattedImage ;
00990
00991 }
00992
00993
00994
00995
00996
00997
00998
00999 if ( blitOnly )
01000 {
01001
01002
01003 #if OSDL_DEBUG
01004
01005 if ( ! targetSurface.isInternalSurfaceAvailable() )
01006 throw ImageException( "Image::LoadLBM : trying to blit image "
01007 "whereas target SDL_surface pointer is null" ) ;
01008
01009 #endif // OSDL_DEBUG
01010
01011
01012 #if OSDL_DEBUG
01013
01014
01015
01016 if ( targetSurface.isLocked() )
01017 throw ImageException( "Image::LoadLBM : trying to blit an image "
01018 "whereas target surface is locked" ) ;
01019
01020 #endif // OSDL_DEBUG
01021
01022 int result = SDL_BlitSurface( image, 0,
01023 & targetSurface.getSDLSurface(), 0 ) ;
01024
01025 if ( result == -1)
01026 throw ImageException( "Image::LoadLBM : error in blit : "
01027 + Utils::getBackendLastError() ) ;
01028
01029 if ( result == -2 )
01030 throw ImageException(
01031 "Image::LoadLBM : video memory was lost during blit." ) ;
01032
01033
01034
01035
01036
01037
01038
01039 SDL_FreeSurface( image ) ;
01040
01041 }
01042 else
01043 {
01044
01045
01046
01047
01048
01049
01050
01051
01052
01053
01054
01055 targetSurface.setSDLSurface( * image ) ;
01056 }
01057
01058
01059
01060
01061
01062
01063
01064
01065
01066
01067
01068
01069 }
01070
01071
01072
01073 void Image::LoadPCX( Surface & targetSurface, const std::string & filename,
01074 bool blitOnly, bool convertToDisplay, bool convertWithAlpha )
01075 throw( ImageException )
01076 {
01077
01078 if ( ! File::Exists( filename ) )
01079 throw ImageException( "Unable to load PCX file "
01080 + filename + " : file not found." ) ;
01081
01082 SDL_Surface * image ;
01083
01084 image = IMG_LoadTyped_RW( SDL_RWFromFile( filename.c_str(), "rb" ),
01085 1, const_cast<char *>( PCXTag.c_str() ) ) ;
01086
01087 if ( image == 0 )
01088 throw ImageException( "Unable to load PCX image stored in " + filename
01089 + " thanks to IMG_Load_RW : "
01090 + string( IMG_GetError() ) ) ;
01091
01092
01093
01094
01095
01096
01097
01098
01099 if ( convertToDisplay )
01100 {
01101
01102
01103 if ( ! VideoModule::IsDisplayInitialized() )
01104 throw ImageException(
01105 "Image::LoadPCX called with request to convert surface "
01106 "to display, whereas display not initialized "
01107 "(VideoModule::setMode never called)." ) ;
01108
01109 SDL_Surface * formattedImage ;
01110
01111
01112
01113
01114
01115
01116
01117 if ( convertWithAlpha )
01118 {
01119
01120 formattedImage = SDL_DisplayFormatAlpha( image ) ;
01121
01122 }
01123 else
01124 {
01125
01126 formattedImage = SDL_DisplayFormat( image ) ;
01127
01128 }
01129
01130 SDL_FreeSurface( image ) ;
01131
01132 image = formattedImage ;
01133
01134 }
01135
01136
01137
01138
01139
01140
01141
01142 if ( blitOnly )
01143 {
01144
01145
01146 #if OSDL_DEBUG
01147
01148 if ( ! targetSurface.isInternalSurfaceAvailable() )
01149 throw ImageException( "Image::LoadPCX : trying to blit image "
01150 "whereas target SDL_surface pointer is null" ) ;
01151
01152 #endif // OSDL_DEBUG
01153
01154
01155 #if OSDL_DEBUG
01156
01157
01158
01159 if ( targetSurface.isLocked() )
01160 throw ImageException( "Image::LoadPCX : trying to blit an image "
01161 "whereas target surface is locked" ) ;
01162
01163 #endif // OSDL_DEBUG
01164
01165 int result = SDL_BlitSurface( image, 0,
01166 & targetSurface.getSDLSurface(), 0 ) ;
01167
01168 if ( result == -1)
01169 throw ImageException( "Image::LoadPCX : error in blit : "
01170 + Utils::getBackendLastError() ) ;
01171
01172 if ( result == -2 )
01173 throw ImageException(
01174 "Image::LoadPCX : video memory was lost during blit." ) ;
01175
01176
01177
01178
01179
01180
01181
01182 SDL_FreeSurface( image ) ;
01183
01184 }
01185 else
01186 {
01187
01188
01189
01190
01191
01192
01193
01194
01195
01196
01197
01198 targetSurface.setSDLSurface( * image ) ;
01199 }
01200
01201
01202
01203
01204
01205
01206
01207
01208
01209
01210
01211
01212 }
01213
01214
01215 void Image::LoadPNM( Surface & targetSurface, const std::string & filename,
01216 bool blitOnly, bool convertToDisplay, bool convertWithAlpha )
01217 throw( ImageException )
01218 {
01219
01220 if ( ! File::Exists( filename ) )
01221 throw ImageException( "Unable to load PNM file "
01222 + filename + " : file not found." ) ;
01223
01224 SDL_Surface * image ;
01225
01226 image = IMG_LoadTyped_RW( SDL_RWFromFile( filename.c_str(), "rb" ),
01227 1, const_cast<char *>( PNMTag.c_str() ) ) ;
01228
01229 if ( image == 0 )
01230 throw ImageException( "Unable to load PNM image stored in " + filename
01231 + " thanks to IMG_Load_RW : "
01232 + string( IMG_GetError() ) ) ;
01233
01234
01235
01236
01237
01238
01239
01240
01241 if ( convertToDisplay )
01242 {
01243
01244 if ( ! VideoModule::IsDisplayInitialized() )
01245 throw ImageException(
01246 "Image::LoadPNM called with request to convert surface "
01247 "to display, whereas display not initialized "
01248 "(VideoModule::setMode never called)." ) ;
01249
01250 SDL_Surface * formattedImage ;
01251
01252
01253
01254
01255
01256
01257
01258 if ( convertWithAlpha )
01259 {
01260
01261 formattedImage = SDL_DisplayFormatAlpha( image ) ;
01262
01263 }
01264 else
01265 {
01266
01267 formattedImage = SDL_DisplayFormat( image ) ;
01268
01269 }
01270
01271 SDL_FreeSurface( image ) ;
01272
01273 image = formattedImage ;
01274
01275 }
01276
01277
01278
01279
01280
01281
01282
01283 if ( blitOnly )
01284 {
01285
01286
01287 #if OSDL_DEBUG
01288
01289 if ( ! targetSurface.isInternalSurfaceAvailable() )
01290 throw ImageException( "Image::LoadPNM : trying to blit image "
01291 "whereas target SDL_surface pointer is null" ) ;
01292
01293 #endif // OSDL_DEBUG
01294
01295
01296 #if OSDL_DEBUG
01297
01298
01299
01300 if ( targetSurface.isLocked() )
01301 throw ImageException( "Image::LoadPNM : trying to blit an image "
01302 "whereas target surface is locked" ) ;
01303 #endif // OSDL_DEBUG
01304
01305 int result = SDL_BlitSurface( image, 0,
01306 & targetSurface.getSDLSurface(), 0 ) ;
01307
01308 if ( result == -1)
01309 throw ImageException( "Image::LoadPNM : error in blit : "
01310 + Utils::getBackendLastError() ) ;
01311
01312 if ( result == -2 )
01313 throw ImageException(
01314 "Image::LoadPNM : video memory was lost during blit." ) ;
01315
01316
01317
01318
01319
01320
01321
01322 SDL_FreeSurface( image ) ;
01323
01324 }
01325 else
01326 {
01327
01328
01329
01330
01331
01332
01333
01334
01335
01336
01337
01338 targetSurface.setSDLSurface( * image ) ;
01339 }
01340
01341
01342
01343
01344
01345
01346
01347
01348
01349
01350
01351 }
01352
01353
01354 void Image::LoadTGA( Surface & targetSurface, const std::string & filename,
01355 bool blitOnly, bool convertToDisplay, bool convertWithAlpha )
01356 throw( ImageException )
01357 {
01358
01359 if ( ! File::Exists( filename ) )
01360 throw ImageException( "Unable to load TGA file "
01361 + filename + " : file not found." ) ;
01362
01363 SDL_Surface * image ;
01364
01365 image = IMG_LoadTyped_RW( SDL_RWFromFile( filename.c_str(), "rb" ),
01366 1, const_cast<char *>( TGATag.c_str() ) ) ;
01367
01368 if ( image == 0 )
01369 throw ImageException( "Unable to load TGA image stored in " + filename
01370 + " thanks to IMG_Load_RW : "
01371 + string( IMG_GetError() ) ) ;
01372
01373
01374
01375
01376
01377
01378
01379
01380 if ( convertToDisplay )
01381 {
01382
01383 if ( ! VideoModule::IsDisplayInitialized() )
01384 throw ImageException(
01385 "Image::LoadTGA called with request to convert surface "
01386 "to display, whereas display not initialized "
01387 "(VideoModule::setMode never called)." ) ;
01388
01389 SDL_Surface * formattedImage ;
01390
01391
01392
01393
01394
01395
01396
01397 if ( convertWithAlpha )
01398 {
01399
01400 formattedImage = SDL_DisplayFormatAlpha( image ) ;
01401
01402 }
01403 else
01404 {
01405
01406 formattedImage = SDL_DisplayFormat( image ) ;
01407
01408 }
01409
01410 SDL_FreeSurface( image ) ;
01411
01412 image = formattedImage ;
01413
01414 }
01415
01416
01417
01418
01419
01420
01421
01422 if ( blitOnly )
01423 {
01424
01425
01426 #if OSDL_DEBUG
01427
01428 if ( ! targetSurface.isInternalSurfaceAvailable() )
01429 throw ImageException( "Image::LoadTGA : trying to blit image "
01430 "whereas target SDL_surface pointer is null" ) ;
01431
01432 #endif // OSDL_DEBUG
01433
01434
01435 #if OSDL_DEBUG
01436
01437
01438
01439 if ( targetSurface.isLocked() )
01440 throw ImageException( "Image::LoadTGA : trying to blit an image "
01441 "whereas target surface is locked" ) ;
01442
01443 #endif // OSDL_DEBUG
01444
01445 int result = SDL_BlitSurface( image, 0,
01446 & targetSurface.getSDLSurface(), 0 ) ;
01447
01448 if ( result == -1)
01449 throw ImageException( "Image::LoadTGA : error in blit : "
01450 + Utils::getBackendLastError() ) ;
01451
01452 if ( result == -2 )
01453 throw ImageException(
01454 "Image::LoadTGA : video memory was lost during blit." ) ;
01455
01456
01457
01458
01459
01460
01461
01462 SDL_FreeSurface( image ) ;
01463
01464 }
01465 else
01466 {
01467
01468
01469
01470
01471
01472
01473
01474
01475
01476
01477
01478 targetSurface.setSDLSurface( * image ) ;
01479 }
01480
01481
01482
01483
01484
01485
01486
01487
01488
01489
01490
01491 }
01492
01493
01494
01495 void Image::LoadXPM( Surface & targetSurface, const std::string & filename,
01496 bool blitOnly, bool convertToDisplay, bool convertWithAlpha )
01497 throw( ImageException )
01498 {
01499
01500 if ( ! File::Exists( filename ) )
01501 throw ImageException( "Unable to load XPM file "
01502 + filename + " : file not found." ) ;
01503
01504 SDL_Surface * image ;
01505
01506 image = IMG_LoadTyped_RW( SDL_RWFromFile( filename.c_str(), "rb" ),
01507 1, const_cast<char *>( XPMTag.c_str() ) ) ;
01508
01509 if ( image == 0 )
01510 throw ImageException( "Unable to load XPM image stored in " + filename
01511 + " thanks to IMG_Load_RW : "
01512 + string( IMG_GetError() ) ) ;
01513
01514
01515
01516
01517
01518
01519
01520
01521 if ( convertToDisplay )
01522 {
01523
01524 if ( ! VideoModule::IsDisplayInitialized() )
01525 throw ImageException(
01526 "Image::LoadXPM called with request to convert surface "
01527 "to display, whereas display not initialized "
01528 "(VideoModule::setMode never called)." ) ;
01529
01530 SDL_Surface * formattedImage ;
01531
01532
01533
01534
01535
01536
01537
01538 if ( convertWithAlpha )
01539 {
01540
01541 formattedImage = SDL_DisplayFormatAlpha( image ) ;
01542
01543 }
01544 else
01545 {
01546
01547 formattedImage = SDL_DisplayFormat( image ) ;
01548
01549 }
01550
01551 SDL_FreeSurface( image ) ;
01552
01553 image = formattedImage ;
01554
01555 }
01556
01557
01558
01559
01560
01561
01562
01563 if ( blitOnly )
01564 {
01565
01566
01567 #if OSDL_DEBUG
01568
01569 if ( ! targetSurface.isInternalSurfaceAvailable() )
01570 throw ImageException( "Image::LoadXPM : trying to blit image "
01571 "whereas target SDL_surface pointer is null" ) ;
01572
01573 #endif // OSDL_DEBUG
01574
01575
01576 #if OSDL_DEBUG
01577
01578
01579
01580 if ( targetSurface.isLocked() )
01581 throw ImageException( "Image::LoadXPM : trying to blit an image "
01582 "whereas target surface is locked" ) ;
01583
01584 #endif // OSDL_DEBUG
01585
01586 int result = SDL_BlitSurface( image, 0,
01587 & targetSurface.getSDLSurface(), 0 ) ;
01588
01589 if ( result == -1)
01590 throw ImageException(
01591 "Image::LoadXPM : error in blit : "
01592 + Utils::getBackendLastError() ) ;
01593
01594 if ( result == -2 )
01595 throw ImageException(
01596 "Image::LoadXPM : video memory was lost during blit." ) ;
01597
01598
01599
01600
01601
01602
01603
01604 SDL_FreeSurface( image ) ;
01605
01606 }
01607 else
01608 {
01609
01610
01611
01612
01613
01614
01615
01616
01617
01618
01619
01620 targetSurface.setSDLSurface( * image ) ;
01621 }
01622
01623
01624
01625
01626
01627
01628
01629
01630
01631
01632
01633
01634 }
01635
01636
01637
01638 void Image::SavePNG( Surface & targetSurface, const std::string & filename,
01639 bool overwrite ) throw( ImageException )
01640 {
01641
01642
01643
01644 if ( ! overwrite && Ceylan::System::File::Exists( filename ) )
01645 throw TwoDimensional::ImageException(
01646 "Surface::savePNG : target file '" + filename
01647 + "' already exists, and overwrite mode is off." ) ;
01648
01649 png_structp png_ptr ;
01650 png_infop info_ptr ;
01651
01652 png_ptr = ::png_create_write_struct( PNG_LIBPNG_VER_STRING, 0, 0, 0 ) ;
01653
01654 if ( png_ptr == 0 )
01655 {
01656 ::png_destroy_write_struct( & png_ptr, (png_infopp) 0 ) ;
01657 throw TwoDimensional::ImageException(
01658 "Surface::savePNG : unable to save image '"
01659 + filename + "' (step 1)" ) ;
01660 }
01661
01662 info_ptr = ::png_create_info_struct( png_ptr ) ;
01663
01664 if ( info_ptr == 0 )
01665 {
01666 ::png_destroy_write_struct( & png_ptr, (png_infopp) 0 ) ;
01667 throw TwoDimensional::ImageException(
01668 "Surface::savePNG : unable to save image '"
01669 + filename + "' (step 2)" ) ;
01670 }
01671
01672
01673 if ( ::setjmp( png_jmpbuf( png_ptr ) ) )
01674 {
01675 ::png_destroy_write_struct( & png_ptr, (png_infopp) 0 ) ;
01676 throw TwoDimensional::ImageException(
01677 "Surface::savePNG : unable to save image '"
01678 + filename + "' (step 3)" ) ;
01679 }
01680
01681
01682
01683
01684
01685
01686
01687
01688
01689
01690
01691
01692
01693
01694
01695
01696 FILE * outputFile = ::fopen( filename.c_str(), "wb" ) ;
01697
01698 if ( outputFile == 0 )
01699 {
01700 ::png_destroy_write_struct( & png_ptr, (png_infopp) 0 ) ;
01701 throw TwoDimensional::ImageException(
01702 "Surface::savePNG : unable to save image '"
01703 + filename + "' (step 4) : " + Ceylan::System::explainError() ) ;
01704 }
01705
01706 ::png_init_io( png_ptr, outputFile ) ;
01707
01708 info_ptr->width = targetSurface.getWidth() ;
01709 info_ptr->height = targetSurface.getHeight() ;
01710
01711
01712
01713
01714
01715
01716 info_ptr->bit_depth = 8 ;
01717
01718
01719
01720
01721
01722
01723
01724
01725
01726 info_ptr->color_type = PNG_COLOR_TYPE_RGB ;
01727
01728
01729
01730
01731
01732
01733
01734
01735
01736
01737
01738
01739
01740
01741
01742
01743
01744
01745
01746
01747
01748
01749
01750
01751
01752
01753
01754
01755
01756
01757
01758
01759
01760
01761
01762
01763
01764
01765
01766
01767
01768
01769
01770
01771
01772
01773 info_ptr->interlace_type = PNG_INTERLACE_ADAM7 ;
01774
01775
01776 info_ptr->num_palette = 0 ;
01777 info_ptr->palette = 0 ;
01778
01779 info_ptr->valid = 0 ;
01780
01781
01782 ::png_write_info( png_ptr, info_ptr ) ;
01783
01784
01785
01786 targetSurface.lock() ;
01787
01788 unsigned char ** png_rows = new unsigned char *
01789 [ targetSurface.getHeight() ] ;
01790
01791 for ( Coordinate y = 0; y < targetSurface.getHeight(); y++ )
01792 {
01793
01794 png_rows[ y ] = new unsigned char[ 3 * targetSurface.getWidth() ] ;
01795
01796 ColorDefinition readDef ;
01797
01798 for ( Coordinate x = 0; x < targetSurface.getWidth(); x++ )
01799 {
01800
01801 readDef = targetSurface.getColorDefinitionAt( x, y ) ;
01802
01803
01804
01805
01806
01807 png_rows[ y ][ x * 3 + 0 ] = readDef.r ;
01808 png_rows[ y ][ x * 3 + 1 ] = readDef.g ;
01809 png_rows[ y ][ x * 3 + 2 ] = readDef.b ;
01810 }
01811 }
01812
01813 targetSurface.unlock() ;
01814
01815 png_write_image( png_ptr, png_rows ) ;
01816
01817 for ( Coordinate y = 0; y < targetSurface.getHeight(); y++ )
01818 delete [] png_rows[ y ] ;
01819
01820 delete [] png_rows ;
01821
01822 ::png_write_end( png_ptr, 0 ) ;
01823
01824 ::png_destroy_write_struct( & png_ptr, & info_ptr ) ;
01825
01826 ::fclose( outputFile ) ;
01827
01828
01829 }
01830
01831
01832
01833 void Image::SaveBMP( Surface & targetSurface, const std::string & filename,
01834 bool overwrite ) throw( ImageException )
01835 {
01836
01837 if ( ! overwrite && Ceylan::System::File::Exists( filename ) )
01838 throw TwoDimensional::ImageException(
01839 "Surface::saveBMP : target file '" + filename
01840 + "' already exists, and overwrite mode is off." ) ;
01841
01842 if ( SDL_SaveBMP( & targetSurface.getSDLSurface(), filename.c_str() ) != 0 )
01843 throw TwoDimensional::ImageException(
01844 "Surface::saveBMP : error while saving BMP file '"
01845 + filename + "' : " + OSDL::Utils::getBackendLastError() ) ;
01846
01847 }
01848
01849
01850
01851 const string Image::toString( Ceylan::VerbosityLevels level ) const throw()
01852 {
01853
01854 if ( _filename.empty() )
01855 return "Image object not linked to a file" ;
01856
01857 return "Image object linked with file " + _filename ;
01858
01859 }
01860