34 #include "util/resource/resource.h"
35 #include "loaders/native/video/imageloader.h"
42 IResource(createUniqueImageName(), loader),
49 Image::Image(
const std::string& name, IResourceLoader* loader):
50 IResource(name, loader),
58 IResource(createUniqueImageName()),
66 Image::Image(
const std::string& name, SDL_Surface* surface):
76 Image::Image(
const uint8_t* data, uint32_t width, uint32_t height):
77 IResource(createUniqueImageName()),
82 SDL_Surface* surface = SDL_CreateRGBSurface(SDL_SWSURFACE | SDL_SRCALPHA, width,height, 32,
83 RMASK, GMASK, BMASK ,AMASK);
84 SDL_LockSurface(surface);
86 uint32_t size = width * height * 4;
87 uint8_t* pixeldata =
static_cast<uint8_t*
>(surface->pixels);
88 std::copy(data, data + size, pixeldata);
89 SDL_UnlockSurface(surface);
93 Image::Image(
const std::string& name,
const uint8_t* data, uint32_t width, uint32_t height):
99 SDL_Surface* surface = SDL_CreateRGBSurface(SDL_SWSURFACE | SDL_SRCALPHA, width,height, 32,
100 RMASK, GMASK, BMASK ,AMASK);
101 SDL_LockSurface(surface);
103 uint32_t size = width * height * 4;
104 uint8_t* pixeldata =
static_cast<uint8_t*
>(surface->pixels);
105 std::copy(data, data + size, pixeldata);
106 SDL_UnlockSurface(surface);
111 if( m_surface && !m_shared) {
112 SDL_FreeSurface(m_surface);
126 m_loader->load(
this);
132 m_state = IResource::RES_LOADED;
137 m_state = IResource::RES_NOT_LOADED;
141 SDL_Surface* srf = m_surface;
146 uint32_t Image::getWidth()
const {
148 return m_subimagerect.
w;
149 }
else if (!m_surface) {
155 uint32_t Image::getHeight()
const {
157 return m_subimagerect.
h;
158 }
else if (!m_surface) {
164 size_t Image::getSize() {
165 if (!m_surface || m_shared) {
168 return m_surface->h * m_surface->pitch;
171 const Rect& Image::getArea()
const {
172 static Rect r(0, 0, getWidth(), getHeight());
176 void Image::getPixelRGBA(int32_t x, int32_t y, uint8_t* r, uint8_t* g, uint8_t* b, uint8_t* a) {
181 int32_t bpp = m_surface->format->BytesPerPixel;
184 if ((x < 0) || (x >= m_surface->w) || (y < 0) || (y >= m_surface->h)) {
188 p = (Uint8*)m_surface->pixels + y * m_surface->pitch + x * bpp;
190 if ((x < 0) || ((x + m_subimagerect.
x) >= m_surface->w) || (y < 0) || ((y + m_subimagerect.
y) >= m_surface->h)) {
194 p = (Uint8*)m_surface->pixels + (y + m_subimagerect.
y) * m_surface->pitch + (x + m_subimagerect.
x) * bpp;
204 pixel = *(Uint16 *)p;
208 if (SDL_BYTEORDER == SDL_BIG_ENDIAN) {
209 pixel = p[0] << 16 | p[1] << 8 | p[2];
211 pixel = p[0] | p[1] << 8 | p[2] << 16;
216 pixel = *(Uint32 *)p;
219 SDL_GetRGBA(pixel, m_surface->format, r, g, b, a);
231 png_bytep *rowpointers = NULL;
233 fp = fopen(filename.c_str(),
"wb");
240 pngptr = png_create_write_struct(PNG_LIBPNG_VER_STRING,
242 if (pngptr == NULL) {
248 infoptr = png_create_info_struct(pngptr);
249 if (infoptr == NULL) {
251 png_destroy_write_struct(&pngptr, (png_infopp)NULL);
255 if (setjmp(png_jmpbuf(pngptr))) {
256 png_destroy_write_struct(&pngptr, &infoptr);
262 png_init_io(pngptr, fp);
265 SDL_LockSurface(const_cast<SDL_Surface*>(&surface));
267 colortype = PNG_COLOR_TYPE_RGB;
268 if(surface.format->palette){
269 colortype |= PNG_COLOR_TYPE_PALETTE;
271 else if (surface.format->Amask){
272 colortype |= PNG_COLOR_TYPE_RGB_ALPHA;
276 png_set_IHDR(pngptr, infoptr, surface.w, surface.h, 8, colortype,
277 PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
279 png_write_info(pngptr, infoptr);
280 png_set_packing(pngptr);
282 rowpointers =
new png_bytep[surface.h];
283 for (int32_t i = 0; i < surface.h; i++) {
284 rowpointers[i] = (png_bytep)(Uint8 *)surface.pixels + i*surface.pitch;
287 png_write_image(pngptr, rowpointers);
288 png_write_end(pngptr, infoptr);
290 SDL_UnlockSurface(const_cast<SDL_Surface*>(&surface));
291 delete [] rowpointers;
292 png_destroy_write_struct(&pngptr, &infoptr);
296 std::string Image::createUniqueImageName() {
298 static uint32_t uniqueNumber = 0;
299 static std::string baseName =
"image";
301 std::ostringstream oss;
302 oss << uniqueNumber <<
"_" << baseName;
304 const std::string name = oss.str();
311 if (!srcimg->m_surface) {
313 }
else if (!m_surface) {
314 m_surface = SDL_CreateRGBSurface(SDL_SWSURFACE | SDL_SRCALPHA, srcimg->getWidth(),
315 srcimg->getHeight(), 32, RMASK, GMASK, BMASK ,AMASK);
317 SDL_SetAlpha(srcimg->m_surface, 0, 0);
321 rect.
x + xoffset, rect.
y + yoffset,
322 static_cast<Uint16
>(srcimg->getWidth()),
323 static_cast<Uint16>(srcimg->getHeight()) };
326 SDL_Rect srcrect = { rect.
x, rect.
y, rect.
w, rect.
h };
327 SDL_BlitSurface(srcimg->m_surface, &srcrect, m_surface, &dstrect);
329 SDL_BlitSurface(srcimg->m_surface, NULL, m_surface, &dstrect);
332 SDL_Rect dstrect = { xoffset, yoffset,
333 static_cast<Uint16
>(srcimg->getWidth()),
334 static_cast<Uint16>(srcimg->getHeight()) };
337 SDL_Rect srcrect = { rect.
x, rect.
y, rect.
w, rect.
h };
338 SDL_BlitSurface(srcimg->m_surface, &srcrect, m_surface, &dstrect);
340 SDL_BlitSurface(srcimg->m_surface, NULL, m_surface, &dstrect);
343 SDL_SetAlpha(srcimg->m_surface, SDL_SRCALPHA, 0);
346 bool Image::putPixel(SDL_Surface* surface, int32_t x, int32_t y, uint8_t r, uint8_t g, uint8_t b, uint8_t a) {
347 if ((x < 0) || (x >= surface->w) || (y < 0) || (y >= surface->h)) {
351 int32_t bpp = surface->format->BytesPerPixel;
352 SDL_LockSurface(surface);
353 Uint8* p = (Uint8*)surface->pixels + y * surface->pitch + x * bpp;
354 Uint32 pixel = SDL_MapRGBA(surface->format, r, g, b, a);
362 *(Uint16 *)p = pixel;
366 if(SDL_BYTEORDER == SDL_BIG_ENDIAN) {
367 p[0] = (pixel >> 16) & 0xff;
368 p[1] = (pixel >> 8) & 0xff;
373 p[1] = (pixel >> 8) & 0xff;
374 p[2] = (pixel >> 16) & 0xff;
379 *(Uint32 *)p = pixel;
382 SDL_UnlockSurface(surface);
Image(IResourceLoader *loader=0)
void reset(SDL_Surface *surface)
void saveImage(const std::string &filename)
const Rect & getSubImageRect() const
SDL_Surface * detachSurface()
static void saveAsPng(const std::string &filename, const SDL_Surface &surface)
virtual void copySubimage(uint32_t xoffset, uint32_t yoffset, const ImagePtr &img)
bool isSharedImage() const