1#include "precompiled.h"
2//
3// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved.
4// Use of this source code is governed by a BSD-style license that can be
5// found in the LICENSE file.
6//
7
8// Image.h: Implements the rx::Image class, an abstract base class for the
9// renderer-specific classes which will define the interface to the underlying
10// surfaces or resources.
11
12#include "libGLESv2/renderer/Image.h"
13
14namespace rx
15{
16
17Image::Image()
18{
19    mWidth = 0;
20    mHeight = 0;
21    mInternalFormat = GL_NONE;
22    mActualFormat = GL_NONE;
23}
24
25void Image::loadAlphaDataToBGRA(GLsizei width, GLsizei height,
26                                int inputPitch, const void *input, size_t outputPitch, void *output)
27{
28    const unsigned char *source = NULL;
29    unsigned char *dest = NULL;
30
31    for (int y = 0; y < height; y++)
32    {
33        source = static_cast<const unsigned char*>(input) + y * inputPitch;
34        dest = static_cast<unsigned char*>(output) + y * outputPitch;
35        for (int x = 0; x < width; x++)
36        {
37            dest[4 * x + 0] = 0;
38            dest[4 * x + 1] = 0;
39            dest[4 * x + 2] = 0;
40            dest[4 * x + 3] = source[x];
41        }
42    }
43}
44
45void Image::loadAlphaDataToNative(GLsizei width, GLsizei height,
46                                  int inputPitch, const void *input, size_t outputPitch, void *output)
47{
48    const unsigned char *source = NULL;
49    unsigned char *dest = NULL;
50
51    for (int y = 0; y < height; y++)
52    {
53        source = static_cast<const unsigned char*>(input) + y * inputPitch;
54        dest = static_cast<unsigned char*>(output) + y * outputPitch;
55        memcpy(dest, source, width);
56    }
57}
58
59void Image::loadAlphaFloatDataToRGBA(GLsizei width, GLsizei height,
60                                     int inputPitch, const void *input, size_t outputPitch, void *output)
61{
62    const float *source = NULL;
63    float *dest = NULL;
64
65    for (int y = 0; y < height; y++)
66    {
67        source = reinterpret_cast<const float*>(static_cast<const unsigned char*>(input) + y * inputPitch);
68        dest = reinterpret_cast<float*>(static_cast<unsigned char*>(output) + y * outputPitch);
69        for (int x = 0; x < width; x++)
70        {
71            dest[4 * x + 0] = 0;
72            dest[4 * x + 1] = 0;
73            dest[4 * x + 2] = 0;
74            dest[4 * x + 3] = source[x];
75        }
76    }
77}
78
79void Image::loadAlphaHalfFloatDataToRGBA(GLsizei width, GLsizei height,
80                                         int inputPitch, const void *input, size_t outputPitch, void *output)
81{
82    const unsigned short *source = NULL;
83    unsigned short *dest = NULL;
84
85    for (int y = 0; y < height; y++)
86    {
87        source = reinterpret_cast<const unsigned short*>(static_cast<const unsigned char*>(input) + y * inputPitch);
88        dest = reinterpret_cast<unsigned short*>(static_cast<unsigned char*>(output) + y * outputPitch);
89        for (int x = 0; x < width; x++)
90        {
91            dest[4 * x + 0] = 0;
92            dest[4 * x + 1] = 0;
93            dest[4 * x + 2] = 0;
94            dest[4 * x + 3] = source[x];
95        }
96    }
97}
98
99void Image::loadLuminanceDataToNativeOrBGRA(GLsizei width, GLsizei height,
100                                            int inputPitch, const void *input, size_t outputPitch, void *output, bool native)
101{
102    const unsigned char *source = NULL;
103    unsigned char *dest = NULL;
104
105    for (int y = 0; y < height; y++)
106    {
107        source = static_cast<const unsigned char*>(input) + y * inputPitch;
108        dest = static_cast<unsigned char*>(output) + y * outputPitch;
109
110        if (!native)   // BGRA8 destination format
111        {
112            for (int x = 0; x < width; x++)
113            {
114                dest[4 * x + 0] = source[x];
115                dest[4 * x + 1] = source[x];
116                dest[4 * x + 2] = source[x];
117                dest[4 * x + 3] = 0xFF;
118            }
119        }
120        else   // L8 destination format
121        {
122            memcpy(dest, source, width);
123        }
124    }
125}
126
127void Image::loadLuminanceFloatDataToRGBA(GLsizei width, GLsizei height,
128                                         int inputPitch, const void *input, size_t outputPitch, void *output)
129{
130    const float *source = NULL;
131    float *dest = NULL;
132
133    for (int y = 0; y < height; y++)
134    {
135        source = reinterpret_cast<const float*>(static_cast<const unsigned char*>(input) + y * inputPitch);
136        dest = reinterpret_cast<float*>(static_cast<unsigned char*>(output) + y * outputPitch);
137        for (int x = 0; x < width; x++)
138        {
139            dest[4 * x + 0] = source[x];
140            dest[4 * x + 1] = source[x];
141            dest[4 * x + 2] = source[x];
142            dest[4 * x + 3] = 1.0f;
143        }
144    }
145}
146
147void Image::loadLuminanceFloatDataToRGB(GLsizei width, GLsizei height,
148                                        int inputPitch, const void *input, size_t outputPitch, void *output)
149{
150    const float *source = NULL;
151    float *dest = NULL;
152
153    for (int y = 0; y < height; y++)
154    {
155        source = reinterpret_cast<const float*>(static_cast<const unsigned char*>(input) + y * inputPitch);
156        dest = reinterpret_cast<float*>(static_cast<unsigned char*>(output) + y * outputPitch);
157        for (int x = 0; x < width; x++)
158        {
159            dest[3 * x + 0] = source[x];
160            dest[3 * x + 1] = source[x];
161            dest[3 * x + 2] = source[x];
162        }
163    }
164}
165
166void Image::loadLuminanceHalfFloatDataToRGBA(GLsizei width, GLsizei height,
167                                             int inputPitch, const void *input, size_t outputPitch, void *output)
168{
169    const unsigned short *source = NULL;
170    unsigned short *dest = NULL;
171
172    for (int y = 0; y < height; y++)
173    {
174        source = reinterpret_cast<const unsigned short*>(static_cast<const unsigned char*>(input) + y * inputPitch);
175        dest = reinterpret_cast<unsigned short*>(static_cast<unsigned char*>(output) + y * outputPitch);
176        for (int x = 0; x < width; x++)
177        {
178            dest[4 * x + 0] = source[x];
179            dest[4 * x + 1] = source[x];
180            dest[4 * x + 2] = source[x];
181            dest[4 * x + 3] = 0x3C00; // SEEEEEMMMMMMMMMM, S = 0, E = 15, M = 0: 16bit flpt representation of 1
182        }
183    }
184}
185
186void Image::loadLuminanceAlphaDataToNativeOrBGRA(GLsizei width, GLsizei height,
187                                                 int inputPitch, const void *input, size_t outputPitch, void *output, bool native)
188{
189    const unsigned char *source = NULL;
190    unsigned char *dest = NULL;
191
192    for (int y = 0; y < height; y++)
193    {
194        source = static_cast<const unsigned char*>(input) + y * inputPitch;
195        dest = static_cast<unsigned char*>(output) + y * outputPitch;
196
197        if (!native)   // BGRA8 destination format
198        {
199            for (int x = 0; x < width; x++)
200            {
201                dest[4 * x + 0] = source[2*x+0];
202                dest[4 * x + 1] = source[2*x+0];
203                dest[4 * x + 2] = source[2*x+0];
204                dest[4 * x + 3] = source[2*x+1];
205            }
206        }
207        else
208        {
209            memcpy(dest, source, width * 2);
210        }
211    }
212}
213
214void Image::loadLuminanceAlphaFloatDataToRGBA(GLsizei width, GLsizei height,
215                                              int inputPitch, const void *input, size_t outputPitch, void *output)
216{
217    const float *source = NULL;
218    float *dest = NULL;
219
220    for (int y = 0; y < height; y++)
221    {
222        source = reinterpret_cast<const float*>(static_cast<const unsigned char*>(input) + y * inputPitch);
223        dest = reinterpret_cast<float*>(static_cast<unsigned char*>(output) + y * outputPitch);
224        for (int x = 0; x < width; x++)
225        {
226            dest[4 * x + 0] = source[2*x+0];
227            dest[4 * x + 1] = source[2*x+0];
228            dest[4 * x + 2] = source[2*x+0];
229            dest[4 * x + 3] = source[2*x+1];
230        }
231    }
232}
233
234void Image::loadLuminanceAlphaHalfFloatDataToRGBA(GLsizei width, GLsizei height,
235                                                  int inputPitch, const void *input, size_t outputPitch, void *output)
236{
237    const unsigned short *source = NULL;
238    unsigned short *dest = NULL;
239
240    for (int y = 0; y < height; y++)
241    {
242        source = reinterpret_cast<const unsigned short*>(static_cast<const unsigned char*>(input) + y * inputPitch);
243        dest = reinterpret_cast<unsigned short*>(static_cast<unsigned char*>(output) + y * outputPitch);
244        for (int x = 0; x < width; x++)
245        {
246            dest[4 * x + 0] = source[2*x+0];
247            dest[4 * x + 1] = source[2*x+0];
248            dest[4 * x + 2] = source[2*x+0];
249            dest[4 * x + 3] = source[2*x+1];
250        }
251    }
252}
253
254void Image::loadRGBUByteDataToBGRX(GLsizei width, GLsizei height,
255                                   int inputPitch, const void *input, size_t outputPitch, void *output)
256{
257    const unsigned char *source = NULL;
258    unsigned char *dest = NULL;
259
260    for (int y = 0; y < height; y++)
261    {
262        source = static_cast<const unsigned char*>(input) + y * inputPitch;
263        dest = static_cast<unsigned char*>(output) + y * outputPitch;
264        for (int x = 0; x < width; x++)
265        {
266            dest[4 * x + 0] = source[x * 3 + 2];
267            dest[4 * x + 1] = source[x * 3 + 1];
268            dest[4 * x + 2] = source[x * 3 + 0];
269            dest[4 * x + 3] = 0xFF;
270        }
271    }
272}
273
274void Image::loadRGBUByteDataToRGBA(GLsizei width, GLsizei height,
275                                   int inputPitch, const void *input, size_t outputPitch, void *output)
276{
277    const unsigned char *source = NULL;
278    unsigned char *dest = NULL;
279
280    for (int y = 0; y < height; y++)
281    {
282        source = static_cast<const unsigned char*>(input) + y * inputPitch;
283        dest = static_cast<unsigned char*>(output) + y * outputPitch;
284        for (int x = 0; x < width; x++)
285        {
286            dest[4 * x + 0] = source[x * 3 + 0];
287            dest[4 * x + 1] = source[x * 3 + 1];
288            dest[4 * x + 2] = source[x * 3 + 2];
289            dest[4 * x + 3] = 0xFF;
290        }
291    }
292}
293
294void Image::loadRGB565DataToBGRA(GLsizei width, GLsizei height,
295                                 int inputPitch, const void *input, size_t outputPitch, void *output)
296{
297    const unsigned short *source = NULL;
298    unsigned char *dest = NULL;
299
300    for (int y = 0; y < height; y++)
301    {
302        source = reinterpret_cast<const unsigned short*>(static_cast<const unsigned char*>(input) + y * inputPitch);
303        dest = static_cast<unsigned char*>(output) + y * outputPitch;
304        for (int x = 0; x < width; x++)
305        {
306            unsigned short rgba = source[x];
307            dest[4 * x + 0] = ((rgba & 0x001F) << 3) | ((rgba & 0x001F) >> 2);
308            dest[4 * x + 1] = ((rgba & 0x07E0) >> 3) | ((rgba & 0x07E0) >> 9);
309            dest[4 * x + 2] = ((rgba & 0xF800) >> 8) | ((rgba & 0xF800) >> 13);
310            dest[4 * x + 3] = 0xFF;
311        }
312    }
313}
314
315void Image::loadRGB565DataToRGBA(GLsizei width, GLsizei height,
316                                 int inputPitch, const void *input, size_t outputPitch, void *output)
317{
318    const unsigned short *source = NULL;
319    unsigned char *dest = NULL;
320
321    for (int y = 0; y < height; y++)
322    {
323        source = reinterpret_cast<const unsigned short*>(static_cast<const unsigned char*>(input) + y * inputPitch);
324        dest = static_cast<unsigned char*>(output) + y * outputPitch;
325        for (int x = 0; x < width; x++)
326        {
327            unsigned short rgba = source[x];
328            dest[4 * x + 0] = ((rgba & 0xF800) >> 8) | ((rgba & 0xF800) >> 13);
329            dest[4 * x + 1] = ((rgba & 0x07E0) >> 3) | ((rgba & 0x07E0) >> 9);
330            dest[4 * x + 2] = ((rgba & 0x001F) << 3) | ((rgba & 0x001F) >> 2);
331            dest[4 * x + 3] = 0xFF;
332        }
333    }
334}
335
336void Image::loadRGBFloatDataToRGBA(GLsizei width, GLsizei height,
337                                   int inputPitch, const void *input, size_t outputPitch, void *output)
338{
339    const float *source = NULL;
340    float *dest = NULL;
341
342    for (int y = 0; y < height; y++)
343    {
344        source = reinterpret_cast<const float*>(static_cast<const unsigned char*>(input) + y * inputPitch);
345        dest = reinterpret_cast<float*>(static_cast<unsigned char*>(output) + y * outputPitch);
346        for (int x = 0; x < width; x++)
347        {
348            dest[4 * x + 0] = source[x * 3 + 0];
349            dest[4 * x + 1] = source[x * 3 + 1];
350            dest[4 * x + 2] = source[x * 3 + 2];
351            dest[4 * x + 3] = 1.0f;
352        }
353    }
354}
355
356void Image::loadRGBFloatDataToNative(GLsizei width, GLsizei height,
357                                     int inputPitch, const void *input, size_t outputPitch, void *output)
358{
359    const float *source = NULL;
360    float *dest = NULL;
361
362    for (int y = 0; y < height; y++)
363    {
364        source = reinterpret_cast<const float*>(static_cast<const unsigned char*>(input) + y * inputPitch);
365        dest = reinterpret_cast<float*>(static_cast<unsigned char*>(output) + y * outputPitch);
366        memcpy(dest, source, width * 12);
367    }
368}
369
370void Image::loadRGBHalfFloatDataToRGBA(GLsizei width, GLsizei height,
371                                       int inputPitch, const void *input, size_t outputPitch, void *output)
372{
373    const unsigned short *source = NULL;
374    unsigned short *dest = NULL;
375
376    for (int y = 0; y < height; y++)
377    {
378        source = reinterpret_cast<const unsigned short*>(static_cast<const unsigned char*>(input) + y * inputPitch);
379        dest = reinterpret_cast<unsigned short*>(static_cast<unsigned char*>(output) + y * outputPitch);
380        for (int x = 0; x < width; x++)
381        {
382            dest[4 * x + 0] = source[x * 3 + 0];
383            dest[4 * x + 1] = source[x * 3 + 1];
384            dest[4 * x + 2] = source[x * 3 + 2];
385            dest[4 * x + 3] = 0x3C00; // SEEEEEMMMMMMMMMM, S = 0, E = 15, M = 0: 16bit flpt representation of 1
386        }
387    }
388}
389
390void Image::loadRGBAUByteDataToBGRA(GLsizei width, GLsizei height,
391                                    int inputPitch, const void *input, size_t outputPitch, void *output)
392{
393    const unsigned int *source = NULL;
394    unsigned int *dest = NULL;
395    for (int y = 0; y < height; y++)
396    {
397        source = reinterpret_cast<const unsigned int*>(static_cast<const unsigned char*>(input) + y * inputPitch);
398        dest = reinterpret_cast<unsigned int*>(static_cast<unsigned char*>(output) + y * outputPitch);
399
400        for (int x = 0; x < width; x++)
401        {
402            unsigned int rgba = source[x];
403            dest[x] = (_rotl(rgba, 16) & 0x00ff00ff) | (rgba & 0xff00ff00);
404        }
405    }
406}
407
408void Image::loadRGBAUByteDataToNative(GLsizei width, GLsizei height,
409                                      int inputPitch, const void *input, size_t outputPitch, void *output)
410{
411    const unsigned int *source = NULL;
412    unsigned int *dest = NULL;
413    for (int y = 0; y < height; y++)
414    {
415        source = reinterpret_cast<const unsigned int*>(static_cast<const unsigned char*>(input) + y * inputPitch);
416        dest = reinterpret_cast<unsigned int*>(static_cast<unsigned char*>(output) + y * outputPitch);
417
418        memcpy(dest, source, width * 4);
419    }
420}
421
422void Image::loadRGBA4444DataToBGRA(GLsizei width, GLsizei height,
423                                   int inputPitch, const void *input, size_t outputPitch, void *output)
424{
425    const unsigned short *source = NULL;
426    unsigned char *dest = NULL;
427
428    for (int y = 0; y < height; y++)
429    {
430        source = reinterpret_cast<const unsigned short*>(static_cast<const unsigned char*>(input) + y * inputPitch);
431        dest = static_cast<unsigned char*>(output) + y * outputPitch;
432        for (int x = 0; x < width; x++)
433        {
434            unsigned short rgba = source[x];
435            dest[4 * x + 0] = ((rgba & 0x00F0) << 0) | ((rgba & 0x00F0) >> 4);
436            dest[4 * x + 1] = ((rgba & 0x0F00) >> 4) | ((rgba & 0x0F00) >> 8);
437            dest[4 * x + 2] = ((rgba & 0xF000) >> 8) | ((rgba & 0xF000) >> 12);
438            dest[4 * x + 3] = ((rgba & 0x000F) << 4) | ((rgba & 0x000F) >> 0);
439        }
440    }
441}
442
443void Image::loadRGBA4444DataToRGBA(GLsizei width, GLsizei height,
444                                   int inputPitch, const void *input, size_t outputPitch, void *output)
445{
446    const unsigned short *source = NULL;
447    unsigned char *dest = NULL;
448
449    for (int y = 0; y < height; y++)
450    {
451        source = reinterpret_cast<const unsigned short*>(static_cast<const unsigned char*>(input) + y * inputPitch);
452        dest = static_cast<unsigned char*>(output) + y * outputPitch;
453        for (int x = 0; x < width; x++)
454        {
455            unsigned short rgba = source[x];
456            dest[4 * x + 0] = ((rgba & 0xF000) >> 8) | ((rgba & 0xF000) >> 12);
457            dest[4 * x + 1] = ((rgba & 0x0F00) >> 4) | ((rgba & 0x0F00) >> 8);
458            dest[4 * x + 2] = ((rgba & 0x00F0) << 0) | ((rgba & 0x00F0) >> 4);
459            dest[4 * x + 3] = ((rgba & 0x000F) << 4) | ((rgba & 0x000F) >> 0);
460        }
461    }
462}
463
464void Image::loadRGBA5551DataToBGRA(GLsizei width, GLsizei height,
465                                   int inputPitch, const void *input, size_t outputPitch, void *output)
466{
467    const unsigned short *source = NULL;
468    unsigned char *dest = NULL;
469
470    for (int y = 0; y < height; y++)
471    {
472        source = reinterpret_cast<const unsigned short*>(static_cast<const unsigned char*>(input) + y * inputPitch);
473        dest = static_cast<unsigned char*>(output) + y * outputPitch;
474        for (int x = 0; x < width; x++)
475        {
476            unsigned short rgba = source[x];
477            dest[4 * x + 0] = ((rgba & 0x003E) << 2) | ((rgba & 0x003E) >> 3);
478            dest[4 * x + 1] = ((rgba & 0x07C0) >> 3) | ((rgba & 0x07C0) >> 8);
479            dest[4 * x + 2] = ((rgba & 0xF800) >> 8) | ((rgba & 0xF800) >> 13);
480            dest[4 * x + 3] = (rgba & 0x0001) ? 0xFF : 0;
481        }
482    }
483}
484
485void Image::loadRGBA5551DataToRGBA(GLsizei width, GLsizei height,
486                                   int inputPitch, const void *input, size_t outputPitch, void *output)
487{
488    const unsigned short *source = NULL;
489    unsigned char *dest = NULL;
490
491    for (int y = 0; y < height; y++)
492    {
493        source = reinterpret_cast<const unsigned short*>(static_cast<const unsigned char*>(input) + y * inputPitch);
494        dest = static_cast<unsigned char*>(output) + y * outputPitch;
495        for (int x = 0; x < width; x++)
496        {
497            unsigned short rgba = source[x];
498            dest[4 * x + 0] = ((rgba & 0xF800) >> 8) | ((rgba & 0xF800) >> 13);
499            dest[4 * x + 1] = ((rgba & 0x07C0) >> 3) | ((rgba & 0x07C0) >> 8);
500            dest[4 * x + 2] = ((rgba & 0x003E) << 2) | ((rgba & 0x003E) >> 3);
501            dest[4 * x + 3] = (rgba & 0x0001) ? 0xFF : 0;
502        }
503    }
504}
505
506void Image::loadRGBAFloatDataToRGBA(GLsizei width, GLsizei height,
507                                    int inputPitch, const void *input, size_t outputPitch, void *output)
508{
509    const float *source = NULL;
510    float *dest = NULL;
511
512    for (int y = 0; y < height; y++)
513    {
514        source = reinterpret_cast<const float*>(static_cast<const unsigned char*>(input) + y * inputPitch);
515        dest = reinterpret_cast<float*>(static_cast<unsigned char*>(output) + y * outputPitch);
516        memcpy(dest, source, width * 16);
517    }
518}
519
520void Image::loadRGBAHalfFloatDataToRGBA(GLsizei width, GLsizei height,
521                                        int inputPitch, const void *input, size_t outputPitch, void *output)
522{
523    const unsigned char *source = NULL;
524    unsigned char *dest = NULL;
525
526    for (int y = 0; y < height; y++)
527    {
528        source = static_cast<const unsigned char*>(input) + y * inputPitch;
529        dest = static_cast<unsigned char*>(output) + y * outputPitch;
530        memcpy(dest, source, width * 8);
531    }
532}
533
534void Image::loadBGRADataToBGRA(GLsizei width, GLsizei height,
535                               int inputPitch, const void *input, size_t outputPitch, void *output)
536{
537    const unsigned char *source = NULL;
538    unsigned char *dest = NULL;
539
540    for (int y = 0; y < height; y++)
541    {
542        source = static_cast<const unsigned char*>(input) + y * inputPitch;
543        dest = static_cast<unsigned char*>(output) + y * outputPitch;
544        memcpy(dest, source, width*4);
545    }
546}
547
548}
549