comparison engine/core/video/image.cpp @ 0:4a0efb7baf70

* Datasets becomes the new trunk and retires after that :-)
author mvbarracuda@33b003aa-7bff-0310-803a-e67f0ece8222
date Sun, 29 Jun 2008 18:44:17 +0000
parents
children d66538926e78
comparison
equal deleted inserted replaced
-1:000000000000 0:4a0efb7baf70
1 /***************************************************************************
2 * Copyright (C) 2005-2008 by the FIFE team *
3 * http://www.fifengine.de *
4 * This file is part of FIFE. *
5 * *
6 * FIFE is free software; you can redistribute it and/or modify *
7 * it under the terms of the GNU General Public License as published by *
8 * the Free Software Foundation; either version 2 of the License, or *
9 * (at your option) any later version. *
10 * *
11 * This program is distributed in the hope that it will be useful, *
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14 * GNU General Public License for more details. *
15 * *
16 * You should have received a copy of the GNU General Public License *
17 * along with this program; if not, write to the *
18 * Free Software Foundation, Inc., *
19 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA *
20 ***************************************************************************/
21
22 // Standard C++ library includes
23 #include <cassert>
24 #include <iostream>
25
26 // 3rd party library includes
27 #include <SDL.h>
28
29 // FIFE includes
30 // These includes are split up in two parts, separated by one empty line
31 // First block: files included from the FIFE root src directory
32 // Second block: files included from the same folder
33 #include "image.h"
34
35 namespace FIFE {
36
37 Image::Image(SDL_Surface* surface):
38 m_location(ResourceLocation("")),
39 m_surface(NULL) {
40 reset(surface);
41 }
42
43 Image::Image(const uint8_t* data, unsigned int width, unsigned int height):
44 m_location(ResourceLocation("")),
45 m_surface(NULL) {
46 SDL_Surface* surface = SDL_CreateRGBSurface(SDL_SWSURFACE | SDL_SRCALPHA, width,height, 32,
47 RMASK, GMASK, BMASK ,AMASK);
48 SDL_LockSurface(surface);
49
50 unsigned int size = width * height * 4;
51 uint8_t* pixeldata = static_cast<uint8_t*>(surface->pixels);
52 std::copy(data, data + size, pixeldata);
53 SDL_UnlockSurface(surface);
54 reset(surface);
55 }
56
57 void Image::reset(SDL_Surface* surface) {
58 if( m_surface ) {
59 SDL_FreeSurface(m_surface);
60 }
61 m_surface = surface;
62 m_xshift = 0;
63 m_yshift = 0;
64 while (!m_clipstack.empty()) {
65 m_clipstack.pop();
66 }
67 m_area.x = m_area.y = m_area.w = m_area.h = 0;
68 m_surface = surface;
69 }
70
71 Image::~Image() {
72 //assert(m_refcount == 0);
73 reset(NULL);
74 }
75
76 SDL_Surface* Image::detachSurface() {
77 SDL_Surface* srf = m_surface;
78 m_surface = NULL;
79 return srf;
80 }
81
82 unsigned int Image::getWidth() const {
83 if (!m_surface) {
84 return 0;
85 }
86 return m_surface->w;
87 }
88
89 unsigned int Image::getHeight() const {
90 if (!m_surface) {
91 return 0;
92 }
93 return m_surface->h;
94 }
95
96 const Rect& Image::getArea() {
97 m_area.w = getWidth();
98 m_area.h = getHeight();
99 return m_area;
100 }
101
102 void Image::setXShift(int xshift) {
103 m_xshift = xshift;
104 }
105
106 void Image::setYShift(int yshift) {
107 m_yshift = yshift;
108 }
109
110 void Image::getPixelRGBA(int x, int y, uint8_t* r, uint8_t* g, uint8_t* b, uint8_t* a) {
111 if ((x < 0) || (x >= m_surface->w) || (y < 0) || (y >= m_surface->h)) {
112 r = 0;
113 g = 0;
114 b = 0;
115 a = 0;
116 return;
117 }
118
119 int bpp = m_surface->format->BytesPerPixel;
120 Uint8 *p = (Uint8*)m_surface->pixels + y * m_surface->pitch + x * bpp;
121 uint32_t pixel;
122 switch(bpp) {
123 case 1:
124 pixel = *p;
125
126 case 2:
127 pixel = *(Uint16 *)p;
128
129 case 3:
130 if (SDL_BYTEORDER == SDL_BIG_ENDIAN) {
131 pixel = p[0] << 16 | p[1] << 8 | p[2];
132 } else {
133 pixel = p[0] | p[1] << 8 | p[2] << 16;
134 }
135
136 case 4:
137 pixel = *(Uint32 *)p;
138 }
139 SDL_GetRGBA(pixel, m_surface->format, r, b, g, a);
140 }
141
142 void Image::render(const Rect& rect, unsigned char alpha) {
143 render(rect, SDL_GetVideoSurface(), alpha);
144 }
145
146 void Image::pushClipArea(const Rect& cliparea, bool clear) {
147 ClipInfo ci;
148 ci.r = cliparea;
149 ci.clearing = clear;
150 m_clipstack.push(ci);
151 setClipArea(cliparea, clear);
152 }
153
154 void Image::popClipArea() {
155 assert(!m_clipstack.empty());
156 m_clipstack.pop();
157 if (m_clipstack.empty()) {
158 clearClipArea();
159 } else {
160 ClipInfo ci = m_clipstack.top();
161 setClipArea(ci.r, ci.clearing);
162 }
163 }
164
165 const Rect& Image::getClipArea() const {
166 if (m_clipstack.empty()) {
167 return m_clipstack.top().r;
168 } else {
169 return m_area;
170 }
171 }
172
173 void Image::clearClipArea() {
174 setClipArea(m_area, true);
175 }
176
177 void Image::saveAsPng(const std::string& filename, SDL_Surface& surface) {
178 FILE *fp;
179 png_structp pngptr;
180 png_infop infoptr;
181 int colortype;
182 png_bytep *rowpointers = NULL;
183 Uint32 rmask, gmask, bmask, amask;
184 //get endian
185 #if SDL_BYTEORDER == SDL_BIG_ENDIAN
186 rmask = 0xff000000; gmask = 0x00ff0000; bmask = 0x0000ff00; amask = 0x000000ff;
187 #else
188 rmask = 0x000000ff; gmask = 0x0000ff00; bmask = 0x00ff0000; amask = 0xff000000;
189 #endif
190
191 fp = fopen(filename.c_str(), "wb");
192
193 if (fp == NULL) {
194 return;
195 }
196
197 //create the png file
198 pngptr = png_create_write_struct(PNG_LIBPNG_VER_STRING,
199 NULL, NULL, NULL);
200 if (pngptr == NULL) {
201 fclose(fp);
202 return;
203 }
204
205 //create information struct
206 infoptr = png_create_info_struct(pngptr);
207 if (infoptr == NULL) {
208 fclose(fp);
209 png_destroy_write_struct(&pngptr, (png_infopp)NULL);
210 return;
211 }
212
213 if (setjmp(png_jmpbuf(pngptr))) {
214 png_destroy_write_struct(&pngptr, &infoptr);
215 fclose(fp);
216 return;
217 }
218
219 //initialize io
220 png_init_io(pngptr, fp);
221
222 //lock the surface for access
223 SDL_LockSurface(&surface);
224
225 colortype = PNG_COLOR_TYPE_RGB;
226 if(m_surface->format->palette){
227 colortype |= PNG_COLOR_TYPE_PALETTE;
228 }
229 else if (m_surface->format->Amask){
230 colortype |= PNG_COLOR_TYPE_RGB_ALPHA;
231 }
232 else{}
233
234 png_set_IHDR(pngptr, infoptr, surface.w, surface.h, 8, colortype,
235 PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
236
237 png_write_info(pngptr, infoptr);
238 png_set_packing(pngptr);
239
240 rowpointers = new png_bytep[surface.h];
241 for (int i = 0; i < surface.h; i++) {
242 rowpointers[i] = (png_bytep)(Uint8 *)surface.pixels + i*surface.pitch;
243 }
244 //write the image
245 png_write_image(pngptr, rowpointers);
246 png_write_end(pngptr, infoptr);
247
248 SDL_UnlockSurface(&surface);
249 delete [] rowpointers;
250 png_destroy_write_struct(&pngptr, &infoptr);
251 fclose(fp);
252
253 }
254 }