1//
2// Copyright (c) 2013-2014 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
7// loadimage.cpp: Defines image loading functions.
8
9#include "libGLESv2/renderer/loadimage.h"
10
11namespace rx
12{
13
14void LoadA8ToRGBA8(size_t width, size_t height, size_t depth,
15                   const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
16                   uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch)
17{
18    for (size_t z = 0; z < depth; z++)
19    {
20        for (size_t y = 0; y < height; y++)
21        {
22            const uint8_t *source = OffsetDataPointer<uint8_t>(input, y, z, inputRowPitch, inputDepthPitch);
23            uint32_t *dest = OffsetDataPointer<uint32_t>(output, y, z, outputRowPitch, outputDepthPitch);
24            for (size_t x = 0; x < width; x++)
25            {
26                dest[x] = static_cast<uint32_t>(source[x]) << 24;
27            }
28        }
29    }
30}
31
32void LoadA8ToBGRA8(size_t width, size_t height, size_t depth,
33                   const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
34                   uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch)
35{
36    // Same as loading to RGBA
37    LoadA8ToRGBA8(width, height, depth, input, inputRowPitch, inputDepthPitch, output, outputRowPitch, outputDepthPitch);
38}
39
40void LoadA32FToRGBA32F(size_t width, size_t height, size_t depth,
41                       const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
42                       uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch)
43{
44    for (size_t z = 0; z < depth; z++)
45    {
46        for (size_t y = 0; y < height; y++)
47        {
48            const float *source = OffsetDataPointer<float>(input, y, z, inputRowPitch, inputDepthPitch);
49            float *dest = OffsetDataPointer<float>(output, y, z, outputRowPitch, outputDepthPitch);
50            for (size_t x = 0; x < width; x++)
51            {
52                dest[4 * x + 0] = 0.0f;
53                dest[4 * x + 1] = 0.0f;
54                dest[4 * x + 2] = 0.0f;
55                dest[4 * x + 3] = source[x];
56            }
57        }
58    }
59}
60
61void LoadA16FToRGBA16F(size_t width, size_t height, size_t depth,
62                       const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
63                       uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch)
64{
65    for (size_t z = 0; z < depth; z++)
66    {
67        for (size_t y = 0; y < height; y++)
68        {
69            const uint16_t *source = OffsetDataPointer<uint16_t>(input, y, z, inputRowPitch, inputDepthPitch);
70            uint16_t *dest = OffsetDataPointer<uint16_t>(output, y, z, outputRowPitch, outputDepthPitch);
71            for (size_t x = 0; x < width; x++)
72            {
73                dest[4 * x + 0] = 0;
74                dest[4 * x + 1] = 0;
75                dest[4 * x + 2] = 0;
76                dest[4 * x + 3] = source[x];
77            }
78        }
79    }
80}
81
82void LoadL8ToRGBA8(size_t width, size_t height, size_t depth,
83                   const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
84                   uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch)
85{
86    for (size_t z = 0; z < depth; z++)
87    {
88        for (size_t y = 0; y < height; y++)
89        {
90            const uint8_t *source = OffsetDataPointer<uint8_t>(input, y, z, inputRowPitch, inputDepthPitch);
91            uint8_t *dest = OffsetDataPointer<uint8_t>(output, y, z, outputRowPitch, outputDepthPitch);
92            for (size_t x = 0; x < width; x++)
93            {
94                dest[4 * x + 0] = source[x];
95                dest[4 * x + 1] = source[x];
96                dest[4 * x + 2] = source[x];
97                dest[4 * x + 3] = 0xFF;
98            }
99        }
100    }
101}
102
103void LoadL8ToBGRA8(size_t width, size_t height, size_t depth,
104                   const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
105                   uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch)
106{
107    // Same as loading to RGBA
108    LoadL8ToRGBA8(width, height, depth, input, inputRowPitch, inputDepthPitch, output, outputRowPitch, outputDepthPitch);
109}
110
111void LoadL32FToRGBA32F(size_t width, size_t height, size_t depth,
112                       const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
113                       uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch)
114{
115    for (size_t z = 0; z < depth; z++)
116    {
117        for (size_t y = 0; y < height; y++)
118        {
119            const float *source = OffsetDataPointer<float>(input, y, z, inputRowPitch, inputDepthPitch);
120            float *dest = OffsetDataPointer<float>(output, y, z, outputRowPitch, outputDepthPitch);
121            for (size_t x = 0; x < width; x++)
122            {
123                dest[4 * x + 0] = source[x];
124                dest[4 * x + 1] = source[x];
125                dest[4 * x + 2] = source[x];
126                dest[4 * x + 3] = 1.0f;
127            }
128        }
129    }
130}
131
132void LoadL16FToRGBA16F(size_t width, size_t height, size_t depth,
133                       const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
134                       uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch)
135{
136    for (size_t z = 0; z < depth; z++)
137    {
138        for (size_t y = 0; y < height; y++)
139        {
140            const uint16_t *source = OffsetDataPointer<uint16_t>(input, y, z, inputRowPitch, inputDepthPitch);
141            uint16_t *dest = OffsetDataPointer<uint16_t>(output, y, z, outputRowPitch, outputDepthPitch);
142            for (size_t x = 0; x < width; x++)
143            {
144                dest[4 * x + 0] = source[x];
145                dest[4 * x + 1] = source[x];
146                dest[4 * x + 2] = source[x];
147                dest[4 * x + 3] = gl::Float16One;
148            }
149        }
150    }
151}
152
153void LoadLA8ToRGBA8(size_t width, size_t height, size_t depth,
154                    const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
155                    uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch)
156{
157    for (size_t z = 0; z < depth; z++)
158    {
159        for (size_t y = 0; y < height; y++)
160        {
161            const uint8_t *source = OffsetDataPointer<uint8_t>(input, y, z, inputRowPitch, inputDepthPitch);
162            uint8_t *dest = OffsetDataPointer<uint8_t>(output, y, z, outputRowPitch, outputDepthPitch);
163            for (size_t x = 0; x < width; x++)
164            {
165                dest[4 * x + 0] = source[2 * x + 0];
166                dest[4 * x + 1] = source[2 * x + 0];
167                dest[4 * x + 2] = source[2 * x + 0];
168                dest[4 * x + 3] = source[2 * x + 1];
169            }
170        }
171    }
172}
173
174void LoadLA8ToBGRA8(size_t width, size_t height, size_t depth,
175                    const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
176                    uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch)
177{
178    // Same as loading to RGBA
179    LoadLA8ToRGBA8(width, height, depth, input, inputRowPitch, inputDepthPitch, output, outputRowPitch, outputDepthPitch);
180}
181
182void LoadLA32FToRGBA32F(size_t width, size_t height, size_t depth,
183                        const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
184                        uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch)
185{
186    for (size_t z = 0; z < depth; z++)
187    {
188        for (size_t y = 0; y < height; y++)
189        {
190            const float *source = OffsetDataPointer<float>(input, y, z, inputRowPitch, inputDepthPitch);
191            float *dest = OffsetDataPointer<float>(output, y, z, outputRowPitch, outputDepthPitch);
192            for (size_t x = 0; x < width; x++)
193            {
194                dest[4 * x + 0] = source[2 * x + 0];
195                dest[4 * x + 1] = source[2 * x + 0];
196                dest[4 * x + 2] = source[2 * x + 0];
197                dest[4 * x + 3] = source[2 * x + 1];
198            }
199        }
200    }
201}
202
203void LoadLA16FToRGBA16F(size_t width, size_t height, size_t depth,
204                        const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
205                        uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch)
206{
207    for (size_t z = 0; z < depth; z++)
208    {
209        for (size_t y = 0; y < height; y++)
210        {
211            const uint16_t *source = OffsetDataPointer<uint16_t>(input, y, z, inputRowPitch, inputDepthPitch);
212            uint16_t *dest = OffsetDataPointer<uint16_t>(output, y, z, outputRowPitch, outputDepthPitch);
213            for (size_t x = 0; x < width; x++)
214            {
215                dest[4 * x + 0] = source[2 * x + 0];
216                dest[4 * x + 1] = source[2 * x + 0];
217                dest[4 * x + 2] = source[2 * x + 0];
218                dest[4 * x + 3] = source[2 * x + 1];
219            }
220        }
221    }
222}
223
224void LoadRGB8ToBGRX8(size_t width, size_t height, size_t depth,
225                     const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
226                     uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch)
227{
228    for (size_t z = 0; z < depth; z++)
229    {
230        for (size_t y = 0; y < height; y++)
231        {
232            const uint8_t *source = OffsetDataPointer<uint8_t>(input, y, z, inputRowPitch, inputDepthPitch);
233            uint8_t *dest = OffsetDataPointer<uint8_t>(output, y, z, outputRowPitch, outputDepthPitch);
234            for (size_t 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}
244
245void LoadRG8ToBGRX8(size_t width, size_t height, size_t depth,
246                    const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
247                    uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch)
248{
249    for (size_t z = 0; z < depth; z++)
250    {
251        for (size_t y = 0; y < height; y++)
252        {
253            const uint8_t *source = OffsetDataPointer<uint8_t>(input, y, z, inputRowPitch, inputDepthPitch);
254            uint8_t *dest = OffsetDataPointer<uint8_t>(output, y, z, outputRowPitch, outputDepthPitch);
255            for (size_t x = 0; x < width; x++)
256            {
257                dest[4 * x + 0] = 0x00;
258                dest[4 * x + 1] = source[x * 2 + 1];
259                dest[4 * x + 2] = source[x * 2 + 0];
260                dest[4 * x + 3] = 0xFF;
261            }
262        }
263    }
264}
265
266void LoadR8ToBGRX8(size_t width, size_t height, size_t depth,
267                   const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
268                   uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch)
269{
270    for (size_t z = 0; z < depth; z++)
271    {
272        for (size_t y = 0; y < height; y++)
273        {
274            const uint8_t *source = OffsetDataPointer<uint8_t>(input, y, z, inputRowPitch, inputDepthPitch);
275            uint8_t *dest = OffsetDataPointer<uint8_t>(output, y, z, outputRowPitch, outputDepthPitch);
276            for (size_t x = 0; x < width; x++)
277            {
278                dest[4 * x + 0] = 0x00;
279                dest[4 * x + 1] = 0x00;
280                dest[4 * x + 2] = source[x];
281                dest[4 * x + 3] = 0xFF;
282            }
283        }
284    }
285}
286
287void LoadR5G6B5ToBGRA8(size_t width, size_t height, size_t depth,
288                       const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
289                       uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch)
290{
291    for (size_t z = 0; z < depth; z++)
292    {
293        for (size_t y = 0; y < height; y++)
294        {
295            const uint16_t *source = OffsetDataPointer<uint16_t>(input, y, z, inputRowPitch, inputDepthPitch);
296            uint8_t *dest = OffsetDataPointer<uint8_t>(output, y, z, outputRowPitch, outputDepthPitch);
297            for (size_t x = 0; x < width; x++)
298            {
299                uint16_t rgb = source[x];
300                dest[4 * x + 0] = ((rgb & 0x001F) << 3) | ((rgb & 0x001F) >> 2);
301                dest[4 * x + 1] = ((rgb & 0x07E0) >> 3) | ((rgb & 0x07E0) >> 9);
302                dest[4 * x + 2] = ((rgb & 0xF800) >> 8) | ((rgb & 0xF800) >> 13);
303                dest[4 * x + 3] = 0xFF;
304            }
305        }
306    }
307}
308
309void LoadR5G6B5ToRGBA8(size_t width, size_t height, size_t depth,
310                       const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
311                       uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch)
312{
313    for (size_t z = 0; z < depth; z++)
314    {
315        for (size_t y = 0; y < height; y++)
316        {
317            const uint16_t *source = OffsetDataPointer<uint16_t>(input, y, z, inputRowPitch, inputDepthPitch);
318            uint8_t *dest = OffsetDataPointer<uint8_t>(output, y, z, outputRowPitch, outputDepthPitch);
319            for (size_t x = 0; x < width; x++)
320            {
321                uint16_t rgb = source[x];
322                dest[4 * x + 0] = ((rgb & 0xF800) >> 8) | ((rgb & 0xF800) >> 13);
323                dest[4 * x + 1] = ((rgb & 0x07E0) >> 3) | ((rgb & 0x07E0) >> 9);
324                dest[4 * x + 2] = ((rgb & 0x001F) << 3) | ((rgb & 0x001F) >> 2);
325                dest[4 * x + 3] = 0xFF;
326            }
327        }
328    }
329}
330
331void LoadRGBA8ToBGRA8(size_t width, size_t height, size_t depth,
332                      const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
333                      uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch)
334{
335    for (size_t z = 0; z < depth; z++)
336    {
337        for (size_t y = 0; y < height; y++)
338        {
339            const uint32_t *source = OffsetDataPointer<uint32_t>(input, y, z, inputRowPitch, inputDepthPitch);
340            uint32_t *dest = OffsetDataPointer<uint32_t>(output, y, z, outputRowPitch, outputDepthPitch);
341            for (size_t x = 0; x < width; x++)
342            {
343                uint32_t rgba = source[x];
344                dest[x] = (_rotl(rgba, 16) & 0x00ff00ff) | (rgba & 0xff00ff00);
345            }
346        }
347    }
348}
349
350void LoadRGBA4ToBGRA8(size_t width, size_t height, size_t depth,
351                      const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
352                      uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch)
353{
354    for (size_t z = 0; z < depth; z++)
355    {
356        for (size_t y = 0; y < height; y++)
357        {
358            const uint16_t *source = OffsetDataPointer<uint16_t>(input, y, z, inputRowPitch, inputDepthPitch);
359            uint8_t *dest = OffsetDataPointer<uint8_t>(output, y, z, outputRowPitch, outputDepthPitch);
360            for (size_t x = 0; x < width; x++)
361            {
362                uint16_t rgba = source[x];
363                dest[4 * x + 0] = ((rgba & 0x00F0) << 0) | ((rgba & 0x00F0) >> 4);
364                dest[4 * x + 1] = ((rgba & 0x0F00) >> 4) | ((rgba & 0x0F00) >> 8);
365                dest[4 * x + 2] = ((rgba & 0xF000) >> 8) | ((rgba & 0xF000) >> 12);
366                dest[4 * x + 3] = ((rgba & 0x000F) << 4) | ((rgba & 0x000F) >> 0);
367            }
368        }
369    }
370}
371
372void LoadRGBA4ToRGBA8(size_t width, size_t height, size_t depth,
373                      const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
374                      uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch)
375{
376    for (size_t z = 0; z < depth; z++)
377    {
378        for (size_t y = 0; y < height; y++)
379        {
380            const uint16_t *source = OffsetDataPointer<uint16_t>(input, y, z, inputRowPitch, inputDepthPitch);
381            uint8_t *dest = OffsetDataPointer<uint8_t>(output, y, z, outputRowPitch, outputDepthPitch);
382            for (size_t x = 0; x < width; x++)
383            {
384                uint16_t rgba = source[x];
385                dest[4 * x + 0] = ((rgba & 0xF000) >> 8) | ((rgba & 0xF000) >> 12);
386                dest[4 * x + 1] = ((rgba & 0x0F00) >> 4) | ((rgba & 0x0F00) >> 8);
387                dest[4 * x + 2] = ((rgba & 0x00F0) << 0) | ((rgba & 0x00F0) >> 4);
388                dest[4 * x + 3] = ((rgba & 0x000F) << 4) | ((rgba & 0x000F) >> 0);
389            }
390        }
391    }
392}
393
394void LoadBGRA4ToBGRA8(size_t width, size_t height, size_t depth,
395                      const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
396                      uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch)
397{
398    for (size_t z = 0; z < depth; z++)
399    {
400        for (size_t y = 0; y < height; y++)
401        {
402            const uint16_t *source = OffsetDataPointer<uint16_t>(input, y, z, inputRowPitch, inputDepthPitch);
403            uint8_t *dest = OffsetDataPointer<uint8_t>(output, y, z, outputRowPitch, outputDepthPitch);
404            for (size_t x = 0; x < width; x++)
405            {
406                uint16_t bgra = source[x];
407                dest[4 * x + 0] = ((bgra & 0xF000) >> 8) | ((bgra & 0xF000) >> 12);
408                dest[4 * x + 1] = ((bgra & 0x0F00) >> 4) | ((bgra & 0x0F00) >> 8);
409                dest[4 * x + 2] = ((bgra & 0x00F0) << 0) | ((bgra & 0x00F0) >> 4);
410                dest[4 * x + 3] = ((bgra & 0x000F) << 4) | ((bgra & 0x000F) >> 0);
411            }
412        }
413    }
414}
415
416void LoadRGB5A1ToBGRA8(size_t width, size_t height, size_t depth,
417                       const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
418                       uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch)
419{
420    for (size_t z = 0; z < depth; z++)
421    {
422        for (size_t y = 0; y < height; y++)
423        {
424            const uint16_t *source = OffsetDataPointer<uint16_t>(input, y, z, inputRowPitch, inputDepthPitch);
425            uint8_t *dest = OffsetDataPointer<uint8_t>(output, y, z, outputRowPitch, outputDepthPitch);
426            for (size_t x = 0; x < width; x++)
427            {
428                uint16_t rgba = source[x];
429                dest[4 * x + 0] = ((rgba & 0x003E) << 2) | ((rgba & 0x003E) >> 3);
430                dest[4 * x + 1] = ((rgba & 0x07C0) >> 3) | ((rgba & 0x07C0) >> 8);
431                dest[4 * x + 2] = ((rgba & 0xF800) >> 8) | ((rgba & 0xF800) >> 13);
432                dest[4 * x + 3] = (rgba & 0x0001) ? 0xFF : 0;
433            }
434        }
435    }
436}
437
438void LoadRGB5A1ToRGBA8(size_t width, size_t height, size_t depth,
439                       const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
440                       uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch)
441{
442    for (size_t z = 0; z < depth; z++)
443    {
444        for (size_t y = 0; y < height; y++)
445        {
446            const uint16_t *source = OffsetDataPointer<uint16_t>(input, y, z, inputRowPitch, inputDepthPitch);
447            uint8_t *dest = OffsetDataPointer<uint8_t>(output, y, z, outputRowPitch, outputDepthPitch);
448            for (size_t x = 0; x < width; x++)
449            {
450                uint16_t rgba = source[x];
451                dest[4 * x + 0] = ((rgba & 0xF800) >> 8) | ((rgba & 0xF800) >> 13);
452                dest[4 * x + 1] = ((rgba & 0x07C0) >> 3) | ((rgba & 0x07C0) >> 8);
453                dest[4 * x + 2] = ((rgba & 0x003E) << 2) | ((rgba & 0x003E) >> 3);
454                dest[4 * x + 3] = (rgba & 0x0001) ? 0xFF : 0;
455            }
456        }
457    }
458}
459
460
461void LoadBGR5A1ToBGRA8(size_t width, size_t height, size_t depth,
462                       const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
463                       uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch)
464{
465    for (size_t z = 0; z < depth; z++)
466    {
467        for (size_t y = 0; y < height; y++)
468        {
469            const uint16_t *source = OffsetDataPointer<uint16_t>(input, y, z, inputRowPitch, inputDepthPitch);
470            uint8_t *dest = OffsetDataPointer<uint8_t>(output, y, z, outputRowPitch, outputDepthPitch);
471            for (size_t x = 0; x < width; x++)
472            {
473                uint16_t bgra = source[x];
474                dest[4 * x + 0] = ((bgra & 0xF800) >> 8) | ((bgra & 0xF800) >> 13);
475                dest[4 * x + 1] = ((bgra & 0x07C0) >> 3) | ((bgra & 0x07C0) >> 8);
476                dest[4 * x + 2] = ((bgra & 0x003E) << 2) | ((bgra & 0x003E) >> 3);
477                dest[4 * x + 3] = (bgra & 0x0001) ? 0xFF : 0;
478            }
479        }
480    }
481}
482
483void LoadRGB10A2ToRGBA8(size_t width, size_t height, size_t depth,
484                        const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
485                        uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch)
486{
487    for (size_t z = 0; z < depth; z++)
488    {
489        for (size_t y = 0; y < height; y++)
490        {
491            const uint32_t *source = OffsetDataPointer<uint32_t>(input, y, z, inputRowPitch, inputDepthPitch);
492            uint8_t *dest = OffsetDataPointer<uint8_t>(output, y, z, outputRowPitch, outputDepthPitch);
493            for (size_t x = 0; x < width; x++)
494            {
495                uint32_t rgba = source[x];
496                dest[4 * x + 0] = (rgba & 0x000003FF) >>  2;
497                dest[4 * x + 1] = (rgba & 0x000FFC00) >> 12;
498                dest[4 * x + 2] = (rgba & 0x3FF00000) >> 22;
499                dest[4 * x + 3] = ((rgba & 0xC0000000) >> 30) * 0x55;
500            }
501        }
502    }
503}
504
505void LoadRGB16FToRGB9E5(size_t width, size_t height, size_t depth,
506                        const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
507                        uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch)
508{
509    for (size_t z = 0; z < depth; z++)
510    {
511        for (size_t y = 0; y < height; y++)
512        {
513            const uint16_t *source = OffsetDataPointer<uint16_t>(input, y, z, inputRowPitch, inputDepthPitch);
514            uint32_t *dest = OffsetDataPointer<uint32_t>(output, y, z, outputRowPitch, outputDepthPitch);
515            for (size_t x = 0; x < width; x++)
516            {
517                dest[x] = gl::convertRGBFloatsTo999E5(gl::float16ToFloat32(source[x * 3 + 0]),
518                                                      gl::float16ToFloat32(source[x * 3 + 1]),
519                                                      gl::float16ToFloat32(source[x * 3 + 2]));
520            }
521        }
522    }
523}
524
525void LoadRGB32FToRGB9E5(size_t width, size_t height, size_t depth,
526                        const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
527                        uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch)
528{
529    for (size_t z = 0; z < depth; z++)
530    {
531        for (size_t y = 0; y < height; y++)
532        {
533            const float *source = OffsetDataPointer<float>(input, y, z, inputRowPitch, inputDepthPitch);
534            uint32_t *dest = OffsetDataPointer<uint32_t>(output, y, z, outputRowPitch, outputDepthPitch);
535            for (size_t x = 0; x < width; x++)
536            {
537                dest[x] = gl::convertRGBFloatsTo999E5(source[x * 3 + 0], source[x * 3 + 1], source[x * 3 + 2]);
538            }
539        }
540    }
541}
542
543void LoadRGB16FToRG11B10F(size_t width, size_t height, size_t depth,
544                          const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
545                          uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch)
546{
547    for (size_t z = 0; z < depth; z++)
548    {
549        for (size_t y = 0; y < height; y++)
550        {
551            const uint16_t *source = OffsetDataPointer<uint16_t>(input, y, z, inputRowPitch, inputDepthPitch);
552            uint32_t *dest = OffsetDataPointer<uint32_t>(output, y, z, outputRowPitch, outputDepthPitch);
553            for (size_t x = 0; x < width; x++)
554            {
555                dest[x] = (gl::float32ToFloat11(gl::float16ToFloat32(source[x * 3 + 0])) <<  0) |
556                          (gl::float32ToFloat11(gl::float16ToFloat32(source[x * 3 + 1])) << 11) |
557                          (gl::float32ToFloat10(gl::float16ToFloat32(source[x * 3 + 2])) << 22);
558            }
559        }
560    }
561}
562
563void LoadRGB32FToRG11B10F(size_t width, size_t height, size_t depth,
564                          const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
565                          uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch)
566{
567    for (size_t z = 0; z < depth; z++)
568    {
569        for (size_t y = 0; y < height; y++)
570        {
571            const float *source = OffsetDataPointer<float>(input, y, z, inputRowPitch, inputDepthPitch);
572            uint32_t *dest = OffsetDataPointer<uint32_t>(output, y, z, outputRowPitch, outputDepthPitch);
573            for (size_t x = 0; x < width; x++)
574            {
575                dest[x] = (gl::float32ToFloat11(source[x * 3 + 0]) <<  0) |
576                          (gl::float32ToFloat11(source[x * 3 + 1]) << 11) |
577                          (gl::float32ToFloat10(source[x * 3 + 2]) << 22);
578            }
579        }
580    }
581}
582
583void LoadG8R24ToR24G8(size_t width, size_t height, size_t depth,
584                      const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
585                      uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch)
586{
587    for (size_t z = 0; z < depth; z++)
588    {
589        for (size_t y = 0; y < height; y++)
590        {
591            const uint32_t *source = OffsetDataPointer<uint32_t>(input, y, z, inputRowPitch, inputDepthPitch);
592            uint32_t *dest = OffsetDataPointer<uint32_t>(output, y, z, outputRowPitch, outputDepthPitch);
593            for (size_t x = 0; x < width; x++)
594            {
595                uint32_t d = source[x] >> 8;
596                uint8_t  s = source[x] & 0xFF;
597                dest[x] = d | (s << 24);
598            }
599        }
600    }
601}
602
603void LoadRGB32FToRGBA16F(size_t width, size_t height, size_t depth,
604                         const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
605                         uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch)
606{
607    for (size_t z = 0; z < depth; z++)
608    {
609        for (size_t y = 0; y < height; y++)
610        {
611            const float *source = OffsetDataPointer<float>(input, y, z, inputRowPitch, inputDepthPitch);
612            uint16_t *dest = OffsetDataPointer<uint16_t>(output, y, z, outputRowPitch, outputDepthPitch);
613            for (size_t x = 0; x < width; x++)
614            {
615                dest[x * 4 + 0] = gl::float32ToFloat16(source[x * 3 + 0]);
616                dest[x * 4 + 1] = gl::float32ToFloat16(source[x * 3 + 1]);
617                dest[x * 4 + 2] = gl::float32ToFloat16(source[x * 3 + 2]);
618                dest[x * 4 + 3] = gl::Float16One;
619            }
620        }
621    }
622}
623
624void LoadR32ToR16(size_t width, size_t height, size_t depth,
625                  const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
626                  uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch)
627{
628    for (size_t z = 0; z < depth; z++)
629    {
630        for (size_t y = 0; y < height; y++)
631        {
632            const uint32_t *source = OffsetDataPointer<uint32_t>(input, y, z, inputRowPitch, inputDepthPitch);
633            uint16_t *dest = OffsetDataPointer<uint16_t>(output, y, z, outputRowPitch, outputDepthPitch);
634            for (size_t x = 0; x < width; x++)
635            {
636                dest[x] = source[x] >> 16;
637            }
638        }
639    }
640}
641
642void LoadR32ToR24G8(size_t width, size_t height, size_t depth,
643                    const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
644                    uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch)
645{
646    for (size_t z = 0; z < depth; z++)
647    {
648        for (size_t y = 0; y < height; y++)
649        {
650            const uint32_t *source = OffsetDataPointer<uint32_t>(input, y, z, inputRowPitch, inputDepthPitch);
651            uint32_t *dest = OffsetDataPointer<uint32_t>(output, y, z, outputRowPitch, outputDepthPitch);
652
653            for (size_t x = 0; x < width; x++)
654            {
655                dest[x] = source[x] >> 8;
656            }
657        }
658    }
659}
660
661}
662