blob: 351fb8f6aba7bd87e1df4b199e2eab232b71ea88 [file] [log] [blame]
daniel@transgaming.comb9d7e6f2012-10-31 19:08:32 +00001//
2// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved.
3// Use of this source code is governed by a BSD-style license that can be
4// found in the LICENSE file.
5//
6
daniel@transgaming.com4ba24062012-12-20 20:54:24 +00007// Image.h: Implements the rx::Image class, an abstract base class for the
8// renderer-specific classes which will define the interface to the underlying
9// surfaces or resources.
10
11#include <GLES2/gl2.h>
12#include <string.h>
13#include <stdlib.h>
daniel@transgaming.comb9d7e6f2012-10-31 19:08:32 +000014
15#include "libGLESv2/renderer/Image.h"
16
daniel@transgaming.com31b13e12012-11-28 19:34:30 +000017namespace rx
daniel@transgaming.comb9d7e6f2012-10-31 19:08:32 +000018{
daniel@transgaming.com0ad830b2012-10-31 19:52:12 +000019
daniel@transgaming.comb9d7e6f2012-10-31 19:08:32 +000020Image::Image()
21{
22 mWidth = 0;
23 mHeight = 0;
24 mInternalFormat = GL_NONE;
daniel@transgaming.com20d36662012-10-31 19:51:43 +000025 mActualFormat = GL_NONE;
daniel@transgaming.comb9d7e6f2012-10-31 19:08:32 +000026}
27
daniel@transgaming.comb9d7e6f2012-10-31 19:08:32 +000028void Image::loadAlphaData(GLsizei width, GLsizei height,
daniel@transgaming.com4ba24062012-12-20 20:54:24 +000029 int inputPitch, const void *input, size_t outputPitch, void *output)
daniel@transgaming.comb9d7e6f2012-10-31 19:08:32 +000030{
31 const unsigned char *source = NULL;
32 unsigned char *dest = NULL;
33
34 for (int y = 0; y < height; y++)
35 {
36 source = static_cast<const unsigned char*>(input) + y * inputPitch;
37 dest = static_cast<unsigned char*>(output) + y * outputPitch;
38 for (int x = 0; x < width; x++)
39 {
40 dest[4 * x + 0] = 0;
41 dest[4 * x + 1] = 0;
42 dest[4 * x + 2] = 0;
43 dest[4 * x + 3] = source[x];
44 }
45 }
46}
47
48void Image::loadAlphaFloatData(GLsizei width, GLsizei height,
daniel@transgaming.com4ba24062012-12-20 20:54:24 +000049 int inputPitch, const void *input, size_t outputPitch, void *output)
daniel@transgaming.comb9d7e6f2012-10-31 19:08:32 +000050{
51 const float *source = NULL;
52 float *dest = NULL;
53
54 for (int y = 0; y < height; y++)
55 {
56 source = reinterpret_cast<const float*>(static_cast<const unsigned char*>(input) + y * inputPitch);
57 dest = reinterpret_cast<float*>(static_cast<unsigned char*>(output) + y * outputPitch);
58 for (int x = 0; x < width; x++)
59 {
60 dest[4 * x + 0] = 0;
61 dest[4 * x + 1] = 0;
62 dest[4 * x + 2] = 0;
63 dest[4 * x + 3] = source[x];
64 }
65 }
66}
67
68void Image::loadAlphaHalfFloatData(GLsizei width, GLsizei height,
daniel@transgaming.com4ba24062012-12-20 20:54:24 +000069 int inputPitch, const void *input, size_t outputPitch, void *output)
daniel@transgaming.comb9d7e6f2012-10-31 19:08:32 +000070{
71 const unsigned short *source = NULL;
72 unsigned short *dest = NULL;
73
74 for (int y = 0; y < height; y++)
75 {
76 source = reinterpret_cast<const unsigned short*>(static_cast<const unsigned char*>(input) + y * inputPitch);
77 dest = reinterpret_cast<unsigned short*>(static_cast<unsigned char*>(output) + y * outputPitch);
78 for (int x = 0; x < width; x++)
79 {
80 dest[4 * x + 0] = 0;
81 dest[4 * x + 1] = 0;
82 dest[4 * x + 2] = 0;
83 dest[4 * x + 3] = source[x];
84 }
85 }
86}
87
88void Image::loadLuminanceData(GLsizei width, GLsizei height,
daniel@transgaming.com4ba24062012-12-20 20:54:24 +000089 int inputPitch, const void *input, size_t outputPitch, void *output, bool native)
daniel@transgaming.comb9d7e6f2012-10-31 19:08:32 +000090{
91 const unsigned char *source = NULL;
92 unsigned char *dest = NULL;
93
94 for (int y = 0; y < height; y++)
95 {
96 source = static_cast<const unsigned char*>(input) + y * inputPitch;
97 dest = static_cast<unsigned char*>(output) + y * outputPitch;
98
99 if (!native) // BGRA8 destination format
100 {
101 for (int x = 0; x < width; x++)
102 {
103 dest[4 * x + 0] = source[x];
104 dest[4 * x + 1] = source[x];
105 dest[4 * x + 2] = source[x];
106 dest[4 * x + 3] = 0xFF;
107 }
108 }
109 else // L8 destination format
110 {
111 memcpy(dest, source, width);
112 }
113 }
114}
115
116void Image::loadLuminanceFloatData(GLsizei width, GLsizei height,
daniel@transgaming.com4ba24062012-12-20 20:54:24 +0000117 int inputPitch, const void *input, size_t outputPitch, void *output)
daniel@transgaming.comb9d7e6f2012-10-31 19:08:32 +0000118{
119 const float *source = NULL;
120 float *dest = NULL;
121
122 for (int y = 0; y < height; y++)
123 {
124 source = reinterpret_cast<const float*>(static_cast<const unsigned char*>(input) + y * inputPitch);
125 dest = reinterpret_cast<float*>(static_cast<unsigned char*>(output) + y * outputPitch);
126 for (int x = 0; x < width; x++)
127 {
128 dest[4 * x + 0] = source[x];
129 dest[4 * x + 1] = source[x];
130 dest[4 * x + 2] = source[x];
131 dest[4 * x + 3] = 1.0f;
132 }
133 }
134}
135
136void Image::loadLuminanceHalfFloatData(GLsizei width, GLsizei height,
daniel@transgaming.com4ba24062012-12-20 20:54:24 +0000137 int inputPitch, const void *input, size_t outputPitch, void *output)
daniel@transgaming.comb9d7e6f2012-10-31 19:08:32 +0000138{
139 const unsigned short *source = NULL;
140 unsigned short *dest = NULL;
141
142 for (int y = 0; y < height; y++)
143 {
144 source = reinterpret_cast<const unsigned short*>(static_cast<const unsigned char*>(input) + y * inputPitch);
145 dest = reinterpret_cast<unsigned short*>(static_cast<unsigned char*>(output) + y * outputPitch);
146 for (int x = 0; x < width; x++)
147 {
148 dest[4 * x + 0] = source[x];
149 dest[4 * x + 1] = source[x];
150 dest[4 * x + 2] = source[x];
151 dest[4 * x + 3] = 0x3C00; // SEEEEEMMMMMMMMMM, S = 0, E = 15, M = 0: 16bit flpt representation of 1
152 }
153 }
154}
155
156void Image::loadLuminanceAlphaData(GLsizei width, GLsizei height,
daniel@transgaming.com4ba24062012-12-20 20:54:24 +0000157 int inputPitch, const void *input, size_t outputPitch, void *output, bool native)
daniel@transgaming.comb9d7e6f2012-10-31 19:08:32 +0000158{
159 const unsigned char *source = NULL;
160 unsigned char *dest = NULL;
161
162 for (int y = 0; y < height; y++)
163 {
164 source = static_cast<const unsigned char*>(input) + y * inputPitch;
165 dest = static_cast<unsigned char*>(output) + y * outputPitch;
166
167 if (!native) // BGRA8 destination format
168 {
169 for (int x = 0; x < width; x++)
170 {
171 dest[4 * x + 0] = source[2*x+0];
172 dest[4 * x + 1] = source[2*x+0];
173 dest[4 * x + 2] = source[2*x+0];
174 dest[4 * x + 3] = source[2*x+1];
175 }
176 }
177 else
178 {
179 memcpy(dest, source, width * 2);
180 }
181 }
182}
183
184void Image::loadLuminanceAlphaFloatData(GLsizei width, GLsizei height,
daniel@transgaming.com4ba24062012-12-20 20:54:24 +0000185 int inputPitch, const void *input, size_t outputPitch, void *output)
daniel@transgaming.comb9d7e6f2012-10-31 19:08:32 +0000186{
187 const float *source = NULL;
188 float *dest = NULL;
189
190 for (int y = 0; y < height; y++)
191 {
192 source = reinterpret_cast<const float*>(static_cast<const unsigned char*>(input) + y * inputPitch);
193 dest = reinterpret_cast<float*>(static_cast<unsigned char*>(output) + y * outputPitch);
194 for (int x = 0; x < width; x++)
195 {
196 dest[4 * x + 0] = source[2*x+0];
197 dest[4 * x + 1] = source[2*x+0];
198 dest[4 * x + 2] = source[2*x+0];
199 dest[4 * x + 3] = source[2*x+1];
200 }
201 }
202}
203
204void Image::loadLuminanceAlphaHalfFloatData(GLsizei width, GLsizei height,
daniel@transgaming.com4ba24062012-12-20 20:54:24 +0000205 int inputPitch, const void *input, size_t outputPitch, void *output)
daniel@transgaming.comb9d7e6f2012-10-31 19:08:32 +0000206{
207 const unsigned short *source = NULL;
208 unsigned short *dest = NULL;
209
210 for (int y = 0; y < height; y++)
211 {
212 source = reinterpret_cast<const unsigned short*>(static_cast<const unsigned char*>(input) + y * inputPitch);
213 dest = reinterpret_cast<unsigned short*>(static_cast<unsigned char*>(output) + y * outputPitch);
214 for (int x = 0; x < width; x++)
215 {
216 dest[4 * x + 0] = source[2*x+0];
217 dest[4 * x + 1] = source[2*x+0];
218 dest[4 * x + 2] = source[2*x+0];
219 dest[4 * x + 3] = source[2*x+1];
220 }
221 }
222}
223
224void Image::loadRGBUByteData(GLsizei width, GLsizei height,
daniel@transgaming.com4ba24062012-12-20 20:54:24 +0000225 int inputPitch, const void *input, size_t outputPitch, void *output)
daniel@transgaming.comb9d7e6f2012-10-31 19:08:32 +0000226{
227 const unsigned char *source = NULL;
228 unsigned char *dest = NULL;
229
230 for (int y = 0; y < height; y++)
231 {
232 source = static_cast<const unsigned char*>(input) + y * inputPitch;
233 dest = static_cast<unsigned char*>(output) + y * outputPitch;
234 for (int x = 0; x < width; x++)
235 {
236 dest[4 * x + 0] = source[x * 3 + 2];
237 dest[4 * x + 1] = source[x * 3 + 1];
238 dest[4 * x + 2] = source[x * 3 + 0];
239 dest[4 * x + 3] = 0xFF;
240 }
241 }
242}
243
244void Image::loadRGB565Data(GLsizei width, GLsizei height,
daniel@transgaming.com4ba24062012-12-20 20:54:24 +0000245 int inputPitch, const void *input, size_t outputPitch, void *output)
daniel@transgaming.comb9d7e6f2012-10-31 19:08:32 +0000246{
247 const unsigned short *source = NULL;
248 unsigned char *dest = NULL;
249
250 for (int y = 0; y < height; y++)
251 {
252 source = reinterpret_cast<const unsigned short*>(static_cast<const unsigned char*>(input) + y * inputPitch);
253 dest = static_cast<unsigned char*>(output) + y * outputPitch;
254 for (int x = 0; x < width; x++)
255 {
256 unsigned short rgba = source[x];
257 dest[4 * x + 0] = ((rgba & 0x001F) << 3) | ((rgba & 0x001F) >> 2);
258 dest[4 * x + 1] = ((rgba & 0x07E0) >> 3) | ((rgba & 0x07E0) >> 9);
259 dest[4 * x + 2] = ((rgba & 0xF800) >> 8) | ((rgba & 0xF800) >> 13);
260 dest[4 * x + 3] = 0xFF;
261 }
262 }
263}
264
265void Image::loadRGBFloatData(GLsizei width, GLsizei height,
daniel@transgaming.com4ba24062012-12-20 20:54:24 +0000266 int inputPitch, const void *input, size_t outputPitch, void *output)
daniel@transgaming.comb9d7e6f2012-10-31 19:08:32 +0000267{
268 const float *source = NULL;
269 float *dest = NULL;
270
271 for (int y = 0; y < height; y++)
272 {
273 source = reinterpret_cast<const float*>(static_cast<const unsigned char*>(input) + y * inputPitch);
274 dest = reinterpret_cast<float*>(static_cast<unsigned char*>(output) + y * outputPitch);
275 for (int x = 0; x < width; x++)
276 {
277 dest[4 * x + 0] = source[x * 3 + 0];
278 dest[4 * x + 1] = source[x * 3 + 1];
279 dest[4 * x + 2] = source[x * 3 + 2];
280 dest[4 * x + 3] = 1.0f;
281 }
282 }
283}
284
285void Image::loadRGBHalfFloatData(GLsizei width, GLsizei height,
daniel@transgaming.com4ba24062012-12-20 20:54:24 +0000286 int inputPitch, const void *input, size_t outputPitch, void *output)
daniel@transgaming.comb9d7e6f2012-10-31 19:08:32 +0000287{
288 const unsigned short *source = NULL;
289 unsigned short *dest = NULL;
290
291 for (int y = 0; y < height; y++)
292 {
293 source = reinterpret_cast<const unsigned short*>(static_cast<const unsigned char*>(input) + y * inputPitch);
294 dest = reinterpret_cast<unsigned short*>(static_cast<unsigned char*>(output) + y * outputPitch);
295 for (int x = 0; x < width; x++)
296 {
297 dest[4 * x + 0] = source[x * 3 + 0];
298 dest[4 * x + 1] = source[x * 3 + 1];
299 dest[4 * x + 2] = source[x * 3 + 2];
300 dest[4 * x + 3] = 0x3C00; // SEEEEEMMMMMMMMMM, S = 0, E = 15, M = 0: 16bit flpt representation of 1
301 }
302 }
303}
304
305void Image::loadRGBAUByteData(GLsizei width, GLsizei height,
daniel@transgaming.com4ba24062012-12-20 20:54:24 +0000306 int inputPitch, const void *input, size_t outputPitch, void *output)
daniel@transgaming.comb9d7e6f2012-10-31 19:08:32 +0000307{
308 const unsigned int *source = NULL;
309 unsigned int *dest = NULL;
310 for (int y = 0; y < height; y++)
311 {
312 source = reinterpret_cast<const unsigned int*>(static_cast<const unsigned char*>(input) + y * inputPitch);
313 dest = reinterpret_cast<unsigned int*>(static_cast<unsigned char*>(output) + y * outputPitch);
314
315 for (int x = 0; x < width; x++)
316 {
317 unsigned int rgba = source[x];
318 dest[x] = (_rotl(rgba, 16) & 0x00ff00ff) | (rgba & 0xff00ff00);
319 }
320 }
321}
322
323void Image::loadRGBA4444Data(GLsizei width, GLsizei height,
daniel@transgaming.com4ba24062012-12-20 20:54:24 +0000324 int inputPitch, const void *input, size_t outputPitch, void *output)
daniel@transgaming.comb9d7e6f2012-10-31 19:08:32 +0000325{
326 const unsigned short *source = NULL;
327 unsigned char *dest = NULL;
328
329 for (int y = 0; y < height; y++)
330 {
331 source = reinterpret_cast<const unsigned short*>(static_cast<const unsigned char*>(input) + y * inputPitch);
332 dest = static_cast<unsigned char*>(output) + y * outputPitch;
333 for (int x = 0; x < width; x++)
334 {
335 unsigned short rgba = source[x];
336 dest[4 * x + 0] = ((rgba & 0x00F0) << 0) | ((rgba & 0x00F0) >> 4);
337 dest[4 * x + 1] = ((rgba & 0x0F00) >> 4) | ((rgba & 0x0F00) >> 8);
338 dest[4 * x + 2] = ((rgba & 0xF000) >> 8) | ((rgba & 0xF000) >> 12);
339 dest[4 * x + 3] = ((rgba & 0x000F) << 4) | ((rgba & 0x000F) >> 0);
340 }
341 }
342}
343
344void Image::loadRGBA5551Data(GLsizei width, GLsizei height,
daniel@transgaming.com4ba24062012-12-20 20:54:24 +0000345 int inputPitch, const void *input, size_t outputPitch, void *output)
daniel@transgaming.comb9d7e6f2012-10-31 19:08:32 +0000346{
347 const unsigned short *source = NULL;
348 unsigned char *dest = NULL;
349
350 for (int y = 0; y < height; y++)
351 {
352 source = reinterpret_cast<const unsigned short*>(static_cast<const unsigned char*>(input) + y * inputPitch);
353 dest = static_cast<unsigned char*>(output) + y * outputPitch;
354 for (int x = 0; x < width; x++)
355 {
356 unsigned short rgba = source[x];
357 dest[4 * x + 0] = ((rgba & 0x003E) << 2) | ((rgba & 0x003E) >> 3);
358 dest[4 * x + 1] = ((rgba & 0x07C0) >> 3) | ((rgba & 0x07C0) >> 8);
359 dest[4 * x + 2] = ((rgba & 0xF800) >> 8) | ((rgba & 0xF800) >> 13);
360 dest[4 * x + 3] = (rgba & 0x0001) ? 0xFF : 0;
361 }
362 }
363}
364
365void Image::loadRGBAFloatData(GLsizei width, GLsizei height,
daniel@transgaming.com4ba24062012-12-20 20:54:24 +0000366 int inputPitch, const void *input, size_t outputPitch, void *output)
daniel@transgaming.comb9d7e6f2012-10-31 19:08:32 +0000367{
368 const float *source = NULL;
369 float *dest = NULL;
370
371 for (int y = 0; y < height; y++)
372 {
373 source = reinterpret_cast<const float*>(static_cast<const unsigned char*>(input) + y * inputPitch);
374 dest = reinterpret_cast<float*>(static_cast<unsigned char*>(output) + y * outputPitch);
375 memcpy(dest, source, width * 16);
376 }
377}
378
379void Image::loadRGBAHalfFloatData(GLsizei width, GLsizei height,
daniel@transgaming.com4ba24062012-12-20 20:54:24 +0000380 int inputPitch, const void *input, size_t outputPitch, void *output)
daniel@transgaming.comb9d7e6f2012-10-31 19:08:32 +0000381{
382 const unsigned char *source = NULL;
383 unsigned char *dest = NULL;
384
385 for (int y = 0; y < height; y++)
386 {
387 source = static_cast<const unsigned char*>(input) + y * inputPitch;
388 dest = static_cast<unsigned char*>(output) + y * outputPitch;
389 memcpy(dest, source, width * 8);
390 }
391}
392
393void Image::loadBGRAData(GLsizei width, GLsizei height,
daniel@transgaming.com4ba24062012-12-20 20:54:24 +0000394 int inputPitch, const void *input, size_t outputPitch, void *output)
daniel@transgaming.comb9d7e6f2012-10-31 19:08:32 +0000395{
396 const unsigned char *source = NULL;
397 unsigned char *dest = NULL;
398
399 for (int y = 0; y < height; y++)
400 {
401 source = static_cast<const unsigned char*>(input) + y * inputPitch;
402 dest = static_cast<unsigned char*>(output) + y * outputPitch;
403 memcpy(dest, source, width*4);
404 }
405}
406
daniel@transgaming.comb9d7e6f2012-10-31 19:08:32 +0000407}