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