2 /*] Copyright (c) 2009-2010, Charles McGarvey [**************************
3 **] All rights reserved.
7 * Distributable under the terms and conditions of the 2-clause BSD license;
8 * see the file COPYING for a complete text of the license.
10 **************************************************************************/
12 #include <cstdio> // FILE
13 #include <cstring> // strncmp
15 #include <boost/algorithm/string.hpp>
30 class Image::Impl
: public Manager
<Impl
>
40 SDL_FreeSurface(mContext
);
47 unsigned char* pixels
= (Uint8
*)(mContext
->pixels
);
49 unsigned pitch
= mContext
->pitch
;
50 unsigned char line
[pitch
];
53 int yEnd
= mContext
->h
- 1;
55 if (SDL_MUSTLOCK(mContext
)) SDL_LockSurface(mContext
);
58 memcpy(line
, pixels
+ pitch
* yBegin
, pitch
);
59 memcpy(pixels
+ pitch
* yBegin
, pixels
+ pitch
* yEnd
, pitch
);
60 memcpy(pixels
+ pitch
* yEnd
, line
, pitch
);
64 if (SDL_MUSTLOCK(mContext
)) SDL_UnlockSurface(mContext
);
67 void setAsIcon() const
69 SDL_WM_SetIcon(mContext
, 0);
73 void init(const std::string
& name
, bool flipped
= false)
75 std::string
path(name
);
77 FILE* fp
= Image::openFile(path
);
80 png_byte signature
[8];
83 png_infop pngInfo
= 0;
84 png_infop pngInfoEnd
= 0;
85 png_structp pngObj
= 0;
99 bytesRead
= fread(signature
, 1, sizeof(signature
), fp
);
100 if (bytesRead
< sizeof(signature
) ||
101 png_sig_cmp(signature
, 0, sizeof(signature
)) != 0) goto cleanup
;
103 pngObj
= png_create_read_struct(PNG_LIBPNG_VER_STRING
, 0, 0, 0);
104 if (!pngObj
) goto cleanup
;
106 pngInfo
= png_create_info_struct(pngObj
);
107 if (!pngInfo
) goto cleanup
;
109 pngInfoEnd
= png_create_info_struct(pngObj
);
110 if (!pngInfoEnd
) goto cleanup
;
112 if (setjmp(png_jmpbuf(pngObj
))) goto cleanup
;
114 png_init_io(pngObj
, fp
);
115 png_set_sig_bytes(pngObj
, sizeof(signature
));
116 png_read_info(pngObj
, pngInfo
);
118 bpp
= png_get_bit_depth(pngObj
, pngInfo
);
119 colors
= png_get_color_type(pngObj
, pngInfo
);
122 case PNG_COLOR_TYPE_PALETTE
:
123 png_set_palette_to_rgb(pngObj
);
126 case PNG_COLOR_TYPE_GRAY
:
127 if (bpp
< 8) png_set_expand(pngObj
);
130 case PNG_COLOR_TYPE_GRAY_ALPHA
:
131 png_set_gray_to_rgb(pngObj
);
135 if (bpp
== 16) png_set_strip_16(pngObj
);
137 png_read_update_info(pngObj
, pngInfo
);
139 bpp
= png_get_bit_depth(pngObj
, pngInfo
);
140 channels
= png_get_channels(pngObj
, pngInfo
);
141 mDepth
= bpp
* channels
;
143 if (channels
== 3) mColorMode
= GL_RGB
;
144 else mColorMode
= GL_RGBA
;
147 png_get_text(pngObj
, pngInfo
, &texts
, &numTexts
);
148 for (int i
= 0; i
< numTexts
; ++i
)
150 if (strncmp(texts
[i
].key
, "TextureInfo", 11) == 0)
152 mComment
= texts
[i
].text
;
157 width
= png_get_image_width(pngObj
, pngInfo
);
158 height
= png_get_image_height(pngObj
, pngInfo
);
160 pitch
= png_get_rowbytes(pngObj
, pngInfo
);
161 mPixels
= new char[width
* pitch
];
163 rows
= new png_bytep
[height
];
166 for (int i
= 0; i
< height
; ++i
)
168 rows
[height
- 1 - i
] = (png_bytep
)(mPixels
+
169 i
* channels
* width
);
174 for (int i
= 0; i
< height
; ++i
)
176 rows
[i
] = (png_bytep
)(mPixels
+ i
* channels
* width
);
180 png_read_image(pngObj
, rows
);
181 png_read_end(pngObj
, 0);
183 mContext
= SDL_CreateRGBSurfaceFrom
190 #if SDL_BYTEORDER == SDL_LIL_ENDIAN
206 png_destroy_read_struct(pngObj
? &pngObj
: 0,
207 pngInfo
? &pngInfo
: 0,
208 pngInfoEnd
? &pngInfoEnd
: 0);
213 SDL_Surface
* mContext
;
219 std::string mComment
;
227 Image::Image(const std::string
& name
) :
229 mImpl(Image::Impl::getInstance(name
)) {}
232 bool Image::isValid() const
234 return mImpl
->mContext
;
237 int Image::getWidth() const
239 return mImpl
->mContext
->w
;
242 int Image::getHeight() const
244 return mImpl
->mContext
->h
;
247 unsigned Image::getDepth() const
249 return mImpl
->mDepth
;
252 unsigned Image::getPitch() const
254 return mImpl
->mContext
->pitch
;
257 GLuint
Image::getMode() const
259 return mImpl
->mColorMode
;
262 std::string
Image::getComment() const
264 return mImpl
->mComment
;
267 const char* Image::getPixels() const
269 return mImpl
->mPixels
;
272 char* Image::getPixels()
274 return mImpl
->mPixels
;
284 void Image::setAsIcon() const
291 bool Image::getPath(std::string
& name
)
293 return Resource::getPath(name
, "images/", "png");
296 FILE* Image::openFile(std::string
& name
)
298 return Resource::openFile(name
, "images/", "png");