1 ////////////////////////////////////////////////////////////////////////////////
2 // Scorched3D (c) 2000-2011
3 //
4 // This file is part of Scorched3D.
5 //
6 // Scorched3D 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 // Scorched3D 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 along
17 // with this program; if not, write to the Free Software Foundation, Inc.,
18 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 ////////////////////////////////////////////////////////////////////////////////
20
21 #include <image/ImageFactory.h>
22 #include <image/ImageBitmapFactory.h>
23 #include <image/ImageJpgFactory.h>
24 #include <image/ImagePngFactory.h>
25 #include <string>
26
ImageFactory()27 ImageFactory::ImageFactory()
28 {
29 }
30
loadImageID(const ImageID & imageId)31 Image ImageFactory::loadImageID(
32 const ImageID &imageId)
33 {
34 ImageID &otherId = (ImageID &) imageId;
35 if (otherId.getImageName()[0] && !otherId.getAlphaName()[0])
36 {
37 return loadImageInternal(otherId.getImageLocation(), otherId.getImageName(), false);
38 }
39 else if (!otherId.getImageName()[0] && otherId.getAlphaName()[0])
40 {
41 return loadImageInternal(otherId.getImageLocation(), otherId.getAlphaName(), true);
42 }
43 else if (otherId.getImageName()[0] && otherId.getAlphaName()[0])
44 {
45 Image bitmap = loadImageInternal(otherId.getImageLocation(), otherId.getImageName(), false);
46 Image alpha = loadImageInternal(otherId.getImageLocation(), otherId.getAlphaName(), false);
47 return combineImage(bitmap, alpha, otherId.getInvert());
48 }
49 return Image();
50 }
51
loadAlphaImage(S3D::FileLocation imageLocation,const std::string & filename)52 Image ImageFactory::loadAlphaImage(
53 S3D::FileLocation imageLocation,
54 const std::string &filename)
55 {
56 ImageID imageId(imageLocation, "", filename);
57 return loadImageID(imageId);
58 }
59
loadImage(S3D::FileLocation imageLocation,const std::string & filename,const std::string & alphafilename,bool invert)60 Image ImageFactory::loadImage(
61 S3D::FileLocation imageLocation,
62 const std::string &filename,
63 const std::string &alphafilename,
64 bool invert)
65 {
66 ImageID imageId(imageLocation, filename, alphafilename, invert);
67 return loadImageID(imageId);
68 }
69
70 #ifndef S3D_SERVER
71
72 #include <GLEXT/GLState.h>
73 #include <common/Defines.h>
74
grabScreen()75 Image ImageFactory::grabScreen()
76 {
77 GLint viewport[4]; /* Current viewport */
78 glGetIntegerv(GL_VIEWPORT, viewport);
79
80 Image map(viewport[2], viewport[3], false);
81
82 glFinish(); /* Finish all OpenGL commands */
83 glPixelStorei(GL_PACK_ALIGNMENT, 4); /* Force 4-byte alignment */
84 glPixelStorei(GL_PACK_ROW_LENGTH, 0);
85 glPixelStorei(GL_PACK_SKIP_ROWS, 0);
86 glPixelStorei(GL_PACK_SKIP_PIXELS, 0);
87
88 glReadPixels(0, 0, map.getWidth(), map.getHeight(),
89 GL_RGB, GL_UNSIGNED_BYTE, map.getBits());
90
91 return map;
92 }
93 #endif
94
loadImageInternal(S3D::FileLocation imageLocation,const std::string & filename,bool loadAlpha)95 Image ImageFactory::loadImageInternal(S3D::FileLocation imageLocation, const std::string &filename, bool loadAlpha)
96 {
97 std::string expandedFilename = S3D::getLocation(imageLocation, filename);
98 if (strstr(filename.c_str(), ".png"))
99 {
100 return ImagePngFactory::loadFromFile(expandedFilename.c_str(), loadAlpha);
101 }
102 else if (strstr(filename.c_str(), ".jpg"))
103 {
104 return ImageJpgFactory::loadFromFile(expandedFilename.c_str(), loadAlpha);
105 }
106 else
107 {
108 return ImageBitmapFactory::loadFromFile(expandedFilename.c_str(), loadAlpha);
109 }
110 }
111
combineImage(Image bitmap,Image alpha,bool invert)112 Image ImageFactory::combineImage(Image bitmap, Image alpha, bool invert)
113 {
114 Image result;
115 if (bitmap.getBits() && alpha.getBits() &&
116 bitmap.getWidth() == alpha.getWidth() &&
117 bitmap.getHeight() == alpha.getHeight())
118 {
119 DIALOG_ASSERT((bitmap.getComponents() == 3 && alpha.getComponents() == 1) ||
120 (bitmap.getComponents() == 3 && alpha.getComponents() == 3) ||
121 (bitmap.getComponents() == 1 && alpha.getComponents() == 3) ||
122 (bitmap.getComponents() == 1 && alpha.getComponents() == 1));
123
124 result = Image(bitmap.getWidth(), bitmap.getHeight(), true);
125
126 unsigned char *bbits = bitmap.getBits();
127 unsigned char *abits = alpha.getBits();
128 unsigned char *bits = result.getBits();
129 for (int y=0; y<bitmap.getHeight(); y++)
130 {
131 for (int x=0; x<bitmap.getWidth(); x++)
132 {
133 bits[0] = bbits[0];
134 if (bitmap.getComponents() > 1)
135 {
136 bits[1] = bbits[1];
137 bits[2] = bbits[2];
138 }
139
140 unsigned char avg = 0;
141 if (alpha.getComponents() == 3) avg = (unsigned char)(int(abits[0] + abits[1] + abits[2]) / 3);
142 else if (alpha.getComponents() == 1) avg = abits[0];
143 if (invert)
144 {
145 bits[3] = (unsigned char)(255 - avg);
146 }
147 else
148 {
149 bits[3] = avg;
150 }
151
152 bbits += bitmap.getComponents();
153 abits += alpha.getComponents();
154 bits += result.getComponents();
155 }
156 }
157 }
158
159 return result;
160 }
161