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>
29 class image::impl
: public manager
<impl
>
39 SDL_FreeSurface(context_
);
46 unsigned char* pixels
= (Uint8
*)(context_
->pixels
);
48 unsigned pitch
= context_
->pitch
;
49 unsigned char line
[pitch
];
52 int yEnd
= context_
->h
- 1;
54 if (SDL_MUSTLOCK(context_
)) SDL_LockSurface(context_
);
57 memcpy(line
, pixels
+ pitch
* yBegin
, pitch
);
58 memcpy(pixels
+ pitch
* yBegin
, pixels
+ pitch
* yEnd
, pitch
);
59 memcpy(pixels
+ pitch
* yEnd
, line
, pitch
);
63 if (SDL_MUSTLOCK(context_
)) SDL_UnlockSurface(context_
);
66 void set_as_icon() const
68 SDL_WM_SetIcon(context_
, 0);
72 void init(const std::string
& name
, bool flipped
= false)
74 std::string
path(name
);
76 FILE* fp
= resource::open_file(path
);
79 png_byte signature
[8];
82 png_infop pngInfo
= 0;
83 png_infop pngInfoEnd
= 0;
84 png_structp pngObj
= 0;
98 bytesRead
= fread(signature
, 1, sizeof(signature
), fp
);
99 if (bytesRead
< sizeof(signature
) ||
100 png_sig_cmp(signature
, 0, sizeof(signature
)) != 0) goto cleanup
;
102 pngObj
= png_create_read_struct(PNG_LIBPNG_VER_STRING
, 0, 0, 0);
103 if (!pngObj
) goto cleanup
;
105 pngInfo
= png_create_info_struct(pngObj
);
106 if (!pngInfo
) goto cleanup
;
108 pngInfoEnd
= png_create_info_struct(pngObj
);
109 if (!pngInfoEnd
) goto cleanup
;
111 if (setjmp(png_jmpbuf(pngObj
))) goto cleanup
;
113 png_init_io(pngObj
, fp
);
114 png_set_sig_bytes(pngObj
, sizeof(signature
));
115 png_read_info(pngObj
, pngInfo
);
117 bpp
= png_get_bit_depth(pngObj
, pngInfo
);
118 colors
= png_get_color_type(pngObj
, pngInfo
);
121 case PNG_COLOR_TYPE_PALETTE
:
122 png_set_palette_to_rgb(pngObj
);
125 case PNG_COLOR_TYPE_GRAY
:
126 if (bpp
< 8) png_set_expand(pngObj
);
129 case PNG_COLOR_TYPE_GRAY_ALPHA
:
130 png_set_gray_to_rgb(pngObj
);
134 if (bpp
== 16) png_set_strip_16(pngObj
);
136 png_read_update_info(pngObj
, pngInfo
);
138 bpp
= png_get_bit_depth(pngObj
, pngInfo
);
139 channels
= png_get_channels(pngObj
, pngInfo
);
140 depth_
= bpp
* channels
;
142 if (channels
== 3) color_mode_
= GL_RGB
;
143 else color_mode_
= GL_RGBA
;
146 png_get_text(pngObj
, pngInfo
, &texts
, &nutext_s
);
147 for (int i
= 0; i
< nutext_s
; ++i
)
149 if (strncmp(texts
[i
].key
, "TextureInfo", 11) == 0)
151 comment_
= texts
[i
].text
;
156 width
= png_get_image_width(pngObj
, pngInfo
);
157 height
= png_get_image_height(pngObj
, pngInfo
);
159 pitch
= png_get_rowbytes(pngObj
, pngInfo
);
160 pixels_
= new char[width
* pitch
];
162 rows
= new png_bytep
[height
];
165 for (int i
= 0; i
< height
; ++i
)
167 rows
[height
- 1 - i
] = (png_bytep
)(pixels_
+
168 i
* channels
* width
);
173 for (int i
= 0; i
< height
; ++i
)
175 rows
[i
] = (png_bytep
)(pixels_
+ i
* channels
* width
);
179 png_read_image(pngObj
, rows
);
180 png_read_end(pngObj
, 0);
182 context_
= SDL_CreateRGBSurfaceFrom
189 #if SDL_BYTEORDER == SDL_LIL_ENDIAN
205 png_destroy_read_struct(pngObj
? &pngObj
: 0,
206 pngInfo
? &pngInfo
: 0,
207 pngInfoEnd
? &pngInfoEnd
: 0);
212 SDL_Surface
* context_
;
218 std::string comment_
;
226 image::image(const std::string
& name
) :
228 impl_(image::impl::instance(name
)) {}
231 bool image::is_valid() const
233 return impl_
->context_
;
236 int image::width() const
238 return impl_
->context_
->w
;
241 int image::height() const
243 return impl_
->context_
->h
;
246 unsigned image::depth() const
248 return impl_
->depth_
;
251 unsigned image::pitch() const
253 return impl_
->context_
->pitch
;
256 GLuint
image::mode() const
258 return impl_
->color_mode_
;
261 std::string
image::comment() const
263 return impl_
->comment_
;
266 const char* image::pixels() const
268 return impl_
->pixels_
;
271 char* image::pixels()
273 return impl_
->pixels_
;
283 void image::set_as_icon() const
286 impl_
->set_as_icon();