• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // Copyright 2013 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 // angle_loadimage.cpp: Defines image loading functions.
8 
9 #include "image_util/loadimage.h"
10 
11 #include "common/mathutil.h"
12 #include "common/platform.h"
13 #include "image_util/imageformats.h"
14 
15 namespace angle
16 {
17 ImageLoadContext::ImageLoadContext()                              = default;
18 ImageLoadContext::~ImageLoadContext()                             = default;
19 ImageLoadContext::ImageLoadContext(const ImageLoadContext &other) = default;
20 
LoadA8ToRGBA8(const ImageLoadContext & context,size_t width,size_t height,size_t depth,const uint8_t * input,size_t inputRowPitch,size_t inputDepthPitch,uint8_t * output,size_t outputRowPitch,size_t outputDepthPitch)21 void LoadA8ToRGBA8(const ImageLoadContext &context,
22                    size_t width,
23                    size_t height,
24                    size_t depth,
25                    const uint8_t *input,
26                    size_t inputRowPitch,
27                    size_t inputDepthPitch,
28                    uint8_t *output,
29                    size_t outputRowPitch,
30                    size_t outputDepthPitch)
31 {
32 #if defined(ANGLE_USE_SSE)
33     if (gl::supportsSSE2())
34     {
35         __m128i zeroWide = _mm_setzero_si128();
36 
37         for (size_t z = 0; z < depth; z++)
38         {
39             for (size_t y = 0; y < height; y++)
40             {
41                 const uint8_t *source =
42                     priv::OffsetDataPointer<uint8_t>(input, y, z, inputRowPitch, inputDepthPitch);
43                 uint32_t *dest = priv::OffsetDataPointer<uint32_t>(output, y, z, outputRowPitch,
44                                                                    outputDepthPitch);
45 
46                 size_t x = 0;
47 
48                 // Make output writes aligned
49                 for (; ((reinterpret_cast<intptr_t>(&dest[x]) & 0xF) != 0 && x < width); x++)
50                 {
51                     dest[x] = static_cast<uint32_t>(source[x]) << 24;
52                 }
53 
54                 for (; x + 7 < width; x += 8)
55                 {
56                     __m128i sourceData =
57                         _mm_loadl_epi64(reinterpret_cast<const __m128i *>(&source[x]));
58                     // Interleave each byte to 16bit, make the lower byte to zero
59                     sourceData = _mm_unpacklo_epi8(zeroWide, sourceData);
60                     // Interleave each 16bit to 32bit, make the lower 16bit to zero
61                     __m128i lo = _mm_unpacklo_epi16(zeroWide, sourceData);
62                     __m128i hi = _mm_unpackhi_epi16(zeroWide, sourceData);
63 
64                     _mm_store_si128(reinterpret_cast<__m128i *>(&dest[x]), lo);
65                     _mm_store_si128(reinterpret_cast<__m128i *>(&dest[x + 4]), hi);
66                 }
67 
68                 // Handle the remainder
69                 for (; x < width; x++)
70                 {
71                     dest[x] = static_cast<uint32_t>(source[x]) << 24;
72                 }
73             }
74         }
75 
76         return;
77     }
78 #endif
79 
80     for (size_t z = 0; z < depth; z++)
81     {
82         for (size_t y = 0; y < height; y++)
83         {
84             const uint8_t *source =
85                 priv::OffsetDataPointer<uint8_t>(input, y, z, inputRowPitch, inputDepthPitch);
86             uint32_t *dest =
87                 priv::OffsetDataPointer<uint32_t>(output, y, z, outputRowPitch, outputDepthPitch);
88             for (size_t x = 0; x < width; x++)
89             {
90                 dest[x] = static_cast<uint32_t>(source[x]) << 24;
91             }
92         }
93     }
94 }
95 
LoadA8ToBGRA8(const ImageLoadContext & context,size_t width,size_t height,size_t depth,const uint8_t * input,size_t inputRowPitch,size_t inputDepthPitch,uint8_t * output,size_t outputRowPitch,size_t outputDepthPitch)96 void LoadA8ToBGRA8(const ImageLoadContext &context,
97                    size_t width,
98                    size_t height,
99                    size_t depth,
100                    const uint8_t *input,
101                    size_t inputRowPitch,
102                    size_t inputDepthPitch,
103                    uint8_t *output,
104                    size_t outputRowPitch,
105                    size_t outputDepthPitch)
106 {
107     // Same as loading to RGBA
108     LoadA8ToRGBA8(context, width, height, depth, input, inputRowPitch, inputDepthPitch, output,
109                   outputRowPitch, outputDepthPitch);
110 }
111 
LoadA32FToRGBA32F(const ImageLoadContext & context,size_t width,size_t height,size_t depth,const uint8_t * input,size_t inputRowPitch,size_t inputDepthPitch,uint8_t * output,size_t outputRowPitch,size_t outputDepthPitch)112 void LoadA32FToRGBA32F(const ImageLoadContext &context,
113                        size_t width,
114                        size_t height,
115                        size_t depth,
116                        const uint8_t *input,
117                        size_t inputRowPitch,
118                        size_t inputDepthPitch,
119                        uint8_t *output,
120                        size_t outputRowPitch,
121                        size_t outputDepthPitch)
122 {
123     for (size_t z = 0; z < depth; z++)
124     {
125         for (size_t y = 0; y < height; y++)
126         {
127             const float *source =
128                 priv::OffsetDataPointer<float>(input, y, z, inputRowPitch, inputDepthPitch);
129             float *dest =
130                 priv::OffsetDataPointer<float>(output, y, z, outputRowPitch, outputDepthPitch);
131             for (size_t x = 0; x < width; x++)
132             {
133                 dest[4 * x + 0] = 0.0f;
134                 dest[4 * x + 1] = 0.0f;
135                 dest[4 * x + 2] = 0.0f;
136                 dest[4 * x + 3] = source[x];
137             }
138         }
139     }
140 }
141 
LoadA16FToRGBA16F(const ImageLoadContext & context,size_t width,size_t height,size_t depth,const uint8_t * input,size_t inputRowPitch,size_t inputDepthPitch,uint8_t * output,size_t outputRowPitch,size_t outputDepthPitch)142 void LoadA16FToRGBA16F(const ImageLoadContext &context,
143                        size_t width,
144                        size_t height,
145                        size_t depth,
146                        const uint8_t *input,
147                        size_t inputRowPitch,
148                        size_t inputDepthPitch,
149                        uint8_t *output,
150                        size_t outputRowPitch,
151                        size_t outputDepthPitch)
152 {
153     for (size_t z = 0; z < depth; z++)
154     {
155         for (size_t y = 0; y < height; y++)
156         {
157             const uint16_t *source =
158                 priv::OffsetDataPointer<uint16_t>(input, y, z, inputRowPitch, inputDepthPitch);
159             uint16_t *dest =
160                 priv::OffsetDataPointer<uint16_t>(output, y, z, outputRowPitch, outputDepthPitch);
161             for (size_t x = 0; x < width; x++)
162             {
163                 dest[4 * x + 0] = 0;
164                 dest[4 * x + 1] = 0;
165                 dest[4 * x + 2] = 0;
166                 dest[4 * x + 3] = source[x];
167             }
168         }
169     }
170 }
171 
LoadL8ToRGBA8(const ImageLoadContext & context,size_t width,size_t height,size_t depth,const uint8_t * input,size_t inputRowPitch,size_t inputDepthPitch,uint8_t * output,size_t outputRowPitch,size_t outputDepthPitch)172 void LoadL8ToRGBA8(const ImageLoadContext &context,
173                    size_t width,
174                    size_t height,
175                    size_t depth,
176                    const uint8_t *input,
177                    size_t inputRowPitch,
178                    size_t inputDepthPitch,
179                    uint8_t *output,
180                    size_t outputRowPitch,
181                    size_t outputDepthPitch)
182 {
183     for (size_t z = 0; z < depth; z++)
184     {
185         for (size_t y = 0; y < height; y++)
186         {
187             const uint8_t *source =
188                 priv::OffsetDataPointer<uint8_t>(input, y, z, inputRowPitch, inputDepthPitch);
189             uint8_t *dest =
190                 priv::OffsetDataPointer<uint8_t>(output, y, z, outputRowPitch, outputDepthPitch);
191             for (size_t x = 0; x < width; x++)
192             {
193                 uint8_t sourceVal = source[x];
194                 dest[4 * x + 0]   = sourceVal;
195                 dest[4 * x + 1]   = sourceVal;
196                 dest[4 * x + 2]   = sourceVal;
197                 dest[4 * x + 3]   = 0xFF;
198             }
199         }
200     }
201 }
202 
LoadL8ToBGRA8(const ImageLoadContext & context,size_t width,size_t height,size_t depth,const uint8_t * input,size_t inputRowPitch,size_t inputDepthPitch,uint8_t * output,size_t outputRowPitch,size_t outputDepthPitch)203 void LoadL8ToBGRA8(const ImageLoadContext &context,
204                    size_t width,
205                    size_t height,
206                    size_t depth,
207                    const uint8_t *input,
208                    size_t inputRowPitch,
209                    size_t inputDepthPitch,
210                    uint8_t *output,
211                    size_t outputRowPitch,
212                    size_t outputDepthPitch)
213 {
214     // Same as loading to RGBA
215     LoadL8ToRGBA8(context, width, height, depth, input, inputRowPitch, inputDepthPitch, output,
216                   outputRowPitch, outputDepthPitch);
217 }
218 
LoadL32FToRGBA32F(const ImageLoadContext & context,size_t width,size_t height,size_t depth,const uint8_t * input,size_t inputRowPitch,size_t inputDepthPitch,uint8_t * output,size_t outputRowPitch,size_t outputDepthPitch)219 void LoadL32FToRGBA32F(const ImageLoadContext &context,
220                        size_t width,
221                        size_t height,
222                        size_t depth,
223                        const uint8_t *input,
224                        size_t inputRowPitch,
225                        size_t inputDepthPitch,
226                        uint8_t *output,
227                        size_t outputRowPitch,
228                        size_t outputDepthPitch)
229 {
230     for (size_t z = 0; z < depth; z++)
231     {
232         for (size_t y = 0; y < height; y++)
233         {
234             const float *source =
235                 priv::OffsetDataPointer<float>(input, y, z, inputRowPitch, inputDepthPitch);
236             float *dest =
237                 priv::OffsetDataPointer<float>(output, y, z, outputRowPitch, outputDepthPitch);
238             for (size_t x = 0; x < width; x++)
239             {
240                 dest[4 * x + 0] = source[x];
241                 dest[4 * x + 1] = source[x];
242                 dest[4 * x + 2] = source[x];
243                 dest[4 * x + 3] = 1.0f;
244             }
245         }
246     }
247 }
248 
LoadL16FToRGBA16F(const ImageLoadContext & context,size_t width,size_t height,size_t depth,const uint8_t * input,size_t inputRowPitch,size_t inputDepthPitch,uint8_t * output,size_t outputRowPitch,size_t outputDepthPitch)249 void LoadL16FToRGBA16F(const ImageLoadContext &context,
250                        size_t width,
251                        size_t height,
252                        size_t depth,
253                        const uint8_t *input,
254                        size_t inputRowPitch,
255                        size_t inputDepthPitch,
256                        uint8_t *output,
257                        size_t outputRowPitch,
258                        size_t outputDepthPitch)
259 {
260     for (size_t z = 0; z < depth; z++)
261     {
262         for (size_t y = 0; y < height; y++)
263         {
264             const uint16_t *source =
265                 priv::OffsetDataPointer<uint16_t>(input, y, z, inputRowPitch, inputDepthPitch);
266             uint16_t *dest =
267                 priv::OffsetDataPointer<uint16_t>(output, y, z, outputRowPitch, outputDepthPitch);
268             for (size_t x = 0; x < width; x++)
269             {
270                 dest[4 * x + 0] = source[x];
271                 dest[4 * x + 1] = source[x];
272                 dest[4 * x + 2] = source[x];
273                 dest[4 * x + 3] = gl::Float16One;
274             }
275         }
276     }
277 }
278 
LoadLA8ToRGBA8(const ImageLoadContext & context,size_t width,size_t height,size_t depth,const uint8_t * input,size_t inputRowPitch,size_t inputDepthPitch,uint8_t * output,size_t outputRowPitch,size_t outputDepthPitch)279 void LoadLA8ToRGBA8(const ImageLoadContext &context,
280                     size_t width,
281                     size_t height,
282                     size_t depth,
283                     const uint8_t *input,
284                     size_t inputRowPitch,
285                     size_t inputDepthPitch,
286                     uint8_t *output,
287                     size_t outputRowPitch,
288                     size_t outputDepthPitch)
289 {
290     for (size_t z = 0; z < depth; z++)
291     {
292         for (size_t y = 0; y < height; y++)
293         {
294             const uint8_t *source =
295                 priv::OffsetDataPointer<uint8_t>(input, y, z, inputRowPitch, inputDepthPitch);
296             uint8_t *dest =
297                 priv::OffsetDataPointer<uint8_t>(output, y, z, outputRowPitch, outputDepthPitch);
298             for (size_t x = 0; x < width; x++)
299             {
300                 dest[4 * x + 0] = source[2 * x + 0];
301                 dest[4 * x + 1] = source[2 * x + 0];
302                 dest[4 * x + 2] = source[2 * x + 0];
303                 dest[4 * x + 3] = source[2 * x + 1];
304             }
305         }
306     }
307 }
308 
LoadLA8ToBGRA8(const ImageLoadContext & context,size_t width,size_t height,size_t depth,const uint8_t * input,size_t inputRowPitch,size_t inputDepthPitch,uint8_t * output,size_t outputRowPitch,size_t outputDepthPitch)309 void LoadLA8ToBGRA8(const ImageLoadContext &context,
310                     size_t width,
311                     size_t height,
312                     size_t depth,
313                     const uint8_t *input,
314                     size_t inputRowPitch,
315                     size_t inputDepthPitch,
316                     uint8_t *output,
317                     size_t outputRowPitch,
318                     size_t outputDepthPitch)
319 {
320     // Same as loading to RGBA
321     LoadLA8ToRGBA8(context, width, height, depth, input, inputRowPitch, inputDepthPitch, output,
322                    outputRowPitch, outputDepthPitch);
323 }
324 
LoadLA32FToRGBA32F(const ImageLoadContext & context,size_t width,size_t height,size_t depth,const uint8_t * input,size_t inputRowPitch,size_t inputDepthPitch,uint8_t * output,size_t outputRowPitch,size_t outputDepthPitch)325 void LoadLA32FToRGBA32F(const ImageLoadContext &context,
326                         size_t width,
327                         size_t height,
328                         size_t depth,
329                         const uint8_t *input,
330                         size_t inputRowPitch,
331                         size_t inputDepthPitch,
332                         uint8_t *output,
333                         size_t outputRowPitch,
334                         size_t outputDepthPitch)
335 {
336     for (size_t z = 0; z < depth; z++)
337     {
338         for (size_t y = 0; y < height; y++)
339         {
340             const float *source =
341                 priv::OffsetDataPointer<float>(input, y, z, inputRowPitch, inputDepthPitch);
342             float *dest =
343                 priv::OffsetDataPointer<float>(output, y, z, outputRowPitch, outputDepthPitch);
344             for (size_t x = 0; x < width; x++)
345             {
346                 dest[4 * x + 0] = source[2 * x + 0];
347                 dest[4 * x + 1] = source[2 * x + 0];
348                 dest[4 * x + 2] = source[2 * x + 0];
349                 dest[4 * x + 3] = source[2 * x + 1];
350             }
351         }
352     }
353 }
354 
LoadLA16FToRGBA16F(const ImageLoadContext & context,size_t width,size_t height,size_t depth,const uint8_t * input,size_t inputRowPitch,size_t inputDepthPitch,uint8_t * output,size_t outputRowPitch,size_t outputDepthPitch)355 void LoadLA16FToRGBA16F(const ImageLoadContext &context,
356                         size_t width,
357                         size_t height,
358                         size_t depth,
359                         const uint8_t *input,
360                         size_t inputRowPitch,
361                         size_t inputDepthPitch,
362                         uint8_t *output,
363                         size_t outputRowPitch,
364                         size_t outputDepthPitch)
365 {
366     for (size_t z = 0; z < depth; z++)
367     {
368         for (size_t y = 0; y < height; y++)
369         {
370             const uint16_t *source =
371                 priv::OffsetDataPointer<uint16_t>(input, y, z, inputRowPitch, inputDepthPitch);
372             uint16_t *dest =
373                 priv::OffsetDataPointer<uint16_t>(output, y, z, outputRowPitch, outputDepthPitch);
374             for (size_t x = 0; x < width; x++)
375             {
376                 dest[4 * x + 0] = source[2 * x + 0];
377                 dest[4 * x + 1] = source[2 * x + 0];
378                 dest[4 * x + 2] = source[2 * x + 0];
379                 dest[4 * x + 3] = source[2 * x + 1];
380             }
381         }
382     }
383 }
384 
LoadRGB8ToBGR565(const ImageLoadContext & context,size_t width,size_t height,size_t depth,const uint8_t * input,size_t inputRowPitch,size_t inputDepthPitch,uint8_t * output,size_t outputRowPitch,size_t outputDepthPitch)385 void LoadRGB8ToBGR565(const ImageLoadContext &context,
386                       size_t width,
387                       size_t height,
388                       size_t depth,
389                       const uint8_t *input,
390                       size_t inputRowPitch,
391                       size_t inputDepthPitch,
392                       uint8_t *output,
393                       size_t outputRowPitch,
394                       size_t outputDepthPitch)
395 {
396     for (size_t z = 0; z < depth; z++)
397     {
398         for (size_t y = 0; y < height; y++)
399         {
400             const uint8_t *source =
401                 priv::OffsetDataPointer<uint8_t>(input, y, z, inputRowPitch, inputDepthPitch);
402             uint16_t *dest =
403                 priv::OffsetDataPointer<uint16_t>(output, y, z, outputRowPitch, outputDepthPitch);
404             for (size_t x = 0; x < width; x++)
405             {
406                 uint8_t r8 = source[x * 3 + 0];
407                 uint8_t g8 = source[x * 3 + 1];
408                 uint8_t b8 = source[x * 3 + 2];
409                 auto r5    = static_cast<uint16_t>(r8 >> 3);
410                 auto g6    = static_cast<uint16_t>(g8 >> 2);
411                 auto b5    = static_cast<uint16_t>(b8 >> 3);
412                 dest[x]    = (r5 << 11) | (g6 << 5) | b5;
413             }
414         }
415     }
416 }
417 
LoadRGB565ToBGR565(const ImageLoadContext & context,size_t width,size_t height,size_t depth,const uint8_t * input,size_t inputRowPitch,size_t inputDepthPitch,uint8_t * output,size_t outputRowPitch,size_t outputDepthPitch)418 void LoadRGB565ToBGR565(const ImageLoadContext &context,
419                         size_t width,
420                         size_t height,
421                         size_t depth,
422                         const uint8_t *input,
423                         size_t inputRowPitch,
424                         size_t inputDepthPitch,
425                         uint8_t *output,
426                         size_t outputRowPitch,
427                         size_t outputDepthPitch)
428 {
429     for (size_t z = 0; z < depth; z++)
430     {
431         for (size_t y = 0; y < height; y++)
432         {
433             const uint16_t *source =
434                 priv::OffsetDataPointer<uint16_t>(input, y, z, inputRowPitch, inputDepthPitch);
435             uint16_t *dest =
436                 priv::OffsetDataPointer<uint16_t>(output, y, z, outputRowPitch, outputDepthPitch);
437             for (size_t x = 0; x < width; x++)
438             {
439                 // The GL type RGB is packed with with red in the MSB, while the D3D11 type BGR
440                 // is packed with red in the LSB
441                 auto rgb    = source[x];
442                 uint16_t r5 = gl::getShiftedData<5, 11>(rgb);
443                 uint16_t g6 = gl::getShiftedData<6, 5>(rgb);
444                 uint16_t b5 = gl::getShiftedData<5, 0>(rgb);
445                 dest[x]     = (r5 << 11) | (g6 << 5) | b5;
446             }
447         }
448     }
449 }
450 
LoadRGB8ToBGRX8(const ImageLoadContext & context,size_t width,size_t height,size_t depth,const uint8_t * input,size_t inputRowPitch,size_t inputDepthPitch,uint8_t * output,size_t outputRowPitch,size_t outputDepthPitch)451 void LoadRGB8ToBGRX8(const ImageLoadContext &context,
452                      size_t width,
453                      size_t height,
454                      size_t depth,
455                      const uint8_t *input,
456                      size_t inputRowPitch,
457                      size_t inputDepthPitch,
458                      uint8_t *output,
459                      size_t outputRowPitch,
460                      size_t outputDepthPitch)
461 {
462     for (size_t z = 0; z < depth; z++)
463     {
464         for (size_t y = 0; y < height; y++)
465         {
466             const uint8_t *source =
467                 priv::OffsetDataPointer<uint8_t>(input, y, z, inputRowPitch, inputDepthPitch);
468             uint8_t *dest =
469                 priv::OffsetDataPointer<uint8_t>(output, y, z, outputRowPitch, outputDepthPitch);
470             for (size_t x = 0; x < width; x++)
471             {
472                 dest[4 * x + 0] = source[x * 3 + 2];
473                 dest[4 * x + 1] = source[x * 3 + 1];
474                 dest[4 * x + 2] = source[x * 3 + 0];
475                 dest[4 * x + 3] = 0xFF;
476             }
477         }
478     }
479 }
480 
LoadRG8ToBGRX8(const ImageLoadContext & context,size_t width,size_t height,size_t depth,const uint8_t * input,size_t inputRowPitch,size_t inputDepthPitch,uint8_t * output,size_t outputRowPitch,size_t outputDepthPitch)481 void LoadRG8ToBGRX8(const ImageLoadContext &context,
482                     size_t width,
483                     size_t height,
484                     size_t depth,
485                     const uint8_t *input,
486                     size_t inputRowPitch,
487                     size_t inputDepthPitch,
488                     uint8_t *output,
489                     size_t outputRowPitch,
490                     size_t outputDepthPitch)
491 {
492     for (size_t z = 0; z < depth; z++)
493     {
494         for (size_t y = 0; y < height; y++)
495         {
496             const uint8_t *source =
497                 priv::OffsetDataPointer<uint8_t>(input, y, z, inputRowPitch, inputDepthPitch);
498             uint8_t *dest =
499                 priv::OffsetDataPointer<uint8_t>(output, y, z, outputRowPitch, outputDepthPitch);
500             for (size_t x = 0; x < width; x++)
501             {
502                 dest[4 * x + 0] = 0x00;
503                 dest[4 * x + 1] = source[x * 2 + 1];
504                 dest[4 * x + 2] = source[x * 2 + 0];
505                 dest[4 * x + 3] = 0xFF;
506             }
507         }
508     }
509 }
510 
LoadR8ToBGRX8(const ImageLoadContext & context,size_t width,size_t height,size_t depth,const uint8_t * input,size_t inputRowPitch,size_t inputDepthPitch,uint8_t * output,size_t outputRowPitch,size_t outputDepthPitch)511 void LoadR8ToBGRX8(const ImageLoadContext &context,
512                    size_t width,
513                    size_t height,
514                    size_t depth,
515                    const uint8_t *input,
516                    size_t inputRowPitch,
517                    size_t inputDepthPitch,
518                    uint8_t *output,
519                    size_t outputRowPitch,
520                    size_t outputDepthPitch)
521 {
522     for (size_t z = 0; z < depth; z++)
523     {
524         for (size_t y = 0; y < height; y++)
525         {
526             const uint8_t *source =
527                 priv::OffsetDataPointer<uint8_t>(input, y, z, inputRowPitch, inputDepthPitch);
528             uint8_t *dest =
529                 priv::OffsetDataPointer<uint8_t>(output, y, z, outputRowPitch, outputDepthPitch);
530             for (size_t x = 0; x < width; x++)
531             {
532                 dest[4 * x + 0] = 0x00;
533                 dest[4 * x + 1] = 0x00;
534                 dest[4 * x + 2] = source[x];
535                 dest[4 * x + 3] = 0xFF;
536             }
537         }
538     }
539 }
540 
LoadR5G6B5ToBGRA8(const ImageLoadContext & context,size_t width,size_t height,size_t depth,const uint8_t * input,size_t inputRowPitch,size_t inputDepthPitch,uint8_t * output,size_t outputRowPitch,size_t outputDepthPitch)541 void LoadR5G6B5ToBGRA8(const ImageLoadContext &context,
542                        size_t width,
543                        size_t height,
544                        size_t depth,
545                        const uint8_t *input,
546                        size_t inputRowPitch,
547                        size_t inputDepthPitch,
548                        uint8_t *output,
549                        size_t outputRowPitch,
550                        size_t outputDepthPitch)
551 {
552     for (size_t z = 0; z < depth; z++)
553     {
554         for (size_t y = 0; y < height; y++)
555         {
556             const uint16_t *source =
557                 priv::OffsetDataPointer<uint16_t>(input, y, z, inputRowPitch, inputDepthPitch);
558             uint8_t *dest =
559                 priv::OffsetDataPointer<uint8_t>(output, y, z, outputRowPitch, outputDepthPitch);
560             for (size_t x = 0; x < width; x++)
561             {
562                 uint16_t rgb = source[x];
563                 dest[4 * x + 0] =
564                     static_cast<uint8_t>(((rgb & 0x001F) << 3) | ((rgb & 0x001F) >> 2));
565                 dest[4 * x + 1] =
566                     static_cast<uint8_t>(((rgb & 0x07E0) >> 3) | ((rgb & 0x07E0) >> 9));
567                 dest[4 * x + 2] =
568                     static_cast<uint8_t>(((rgb & 0xF800) >> 8) | ((rgb & 0xF800) >> 13));
569                 dest[4 * x + 3] = 0xFF;
570             }
571         }
572     }
573 }
574 
LoadR5G6B5ToRGBA8(const ImageLoadContext & context,size_t width,size_t height,size_t depth,const uint8_t * input,size_t inputRowPitch,size_t inputDepthPitch,uint8_t * output,size_t outputRowPitch,size_t outputDepthPitch)575 void LoadR5G6B5ToRGBA8(const ImageLoadContext &context,
576                        size_t width,
577                        size_t height,
578                        size_t depth,
579                        const uint8_t *input,
580                        size_t inputRowPitch,
581                        size_t inputDepthPitch,
582                        uint8_t *output,
583                        size_t outputRowPitch,
584                        size_t outputDepthPitch)
585 {
586     for (size_t z = 0; z < depth; z++)
587     {
588         for (size_t y = 0; y < height; y++)
589         {
590             const uint16_t *source =
591                 priv::OffsetDataPointer<uint16_t>(input, y, z, inputRowPitch, inputDepthPitch);
592             uint8_t *dest =
593                 priv::OffsetDataPointer<uint8_t>(output, y, z, outputRowPitch, outputDepthPitch);
594             for (size_t x = 0; x < width; x++)
595             {
596                 uint16_t rgb = source[x];
597                 dest[4 * x + 0] =
598                     static_cast<uint8_t>(((rgb & 0xF800) >> 8) | ((rgb & 0xF800) >> 13));
599                 dest[4 * x + 1] =
600                     static_cast<uint8_t>(((rgb & 0x07E0) >> 3) | ((rgb & 0x07E0) >> 9));
601                 dest[4 * x + 2] =
602                     static_cast<uint8_t>(((rgb & 0x001F) << 3) | ((rgb & 0x001F) >> 2));
603                 dest[4 * x + 3] = 0xFF;
604             }
605         }
606     }
607 }
608 
LoadRGBA8ToBGRA8(const ImageLoadContext & context,size_t width,size_t height,size_t depth,const uint8_t * input,size_t inputRowPitch,size_t inputDepthPitch,uint8_t * output,size_t outputRowPitch,size_t outputDepthPitch)609 void LoadRGBA8ToBGRA8(const ImageLoadContext &context,
610                       size_t width,
611                       size_t height,
612                       size_t depth,
613                       const uint8_t *input,
614                       size_t inputRowPitch,
615                       size_t inputDepthPitch,
616                       uint8_t *output,
617                       size_t outputRowPitch,
618                       size_t outputDepthPitch)
619 {
620 #if defined(ANGLE_USE_SSE)
621     if (gl::supportsSSE2())
622     {
623         __m128i brMask = _mm_set1_epi32(0x00ff00ff);
624 
625         for (size_t z = 0; z < depth; z++)
626         {
627             for (size_t y = 0; y < height; y++)
628             {
629                 const uint32_t *source =
630                     priv::OffsetDataPointer<uint32_t>(input, y, z, inputRowPitch, inputDepthPitch);
631                 uint32_t *dest = priv::OffsetDataPointer<uint32_t>(output, y, z, outputRowPitch,
632                                                                    outputDepthPitch);
633 
634                 size_t x = 0;
635 
636                 // Make output writes aligned
637                 for (; ((reinterpret_cast<intptr_t>(&dest[x]) & 15) != 0) && x < width; x++)
638                 {
639                     uint32_t rgba = source[x];
640                     dest[x]       = (ANGLE_ROTL(rgba, 16) & 0x00ff00ff) | (rgba & 0xff00ff00);
641                 }
642 
643                 for (; x + 3 < width; x += 4)
644                 {
645                     __m128i sourceData =
646                         _mm_loadu_si128(reinterpret_cast<const __m128i *>(&source[x]));
647                     // Mask out g and a, which don't change
648                     __m128i gaComponents = _mm_andnot_si128(brMask, sourceData);
649                     // Mask out b and r
650                     __m128i brComponents = _mm_and_si128(sourceData, brMask);
651                     // Swap b and r
652                     __m128i brSwapped = _mm_shufflehi_epi16(
653                         _mm_shufflelo_epi16(brComponents, _MM_SHUFFLE(2, 3, 0, 1)),
654                         _MM_SHUFFLE(2, 3, 0, 1));
655                     __m128i result = _mm_or_si128(gaComponents, brSwapped);
656                     _mm_store_si128(reinterpret_cast<__m128i *>(&dest[x]), result);
657                 }
658 
659                 // Perform leftover writes
660                 for (; x < width; x++)
661                 {
662                     uint32_t rgba = source[x];
663                     dest[x]       = (ANGLE_ROTL(rgba, 16) & 0x00ff00ff) | (rgba & 0xff00ff00);
664                 }
665             }
666         }
667 
668         return;
669     }
670 #endif
671 
672     for (size_t z = 0; z < depth; z++)
673     {
674         for (size_t y = 0; y < height; y++)
675         {
676             const uint32_t *source =
677                 priv::OffsetDataPointer<uint32_t>(input, y, z, inputRowPitch, inputDepthPitch);
678             uint32_t *dest =
679                 priv::OffsetDataPointer<uint32_t>(output, y, z, outputRowPitch, outputDepthPitch);
680             for (size_t x = 0; x < width; x++)
681             {
682                 uint32_t rgba = source[x];
683                 dest[x]       = (ANGLE_ROTL(rgba, 16) & 0x00ff00ff) | (rgba & 0xff00ff00);
684             }
685         }
686     }
687 }
688 
LoadRGBA8ToBGRA4(const ImageLoadContext & context,size_t width,size_t height,size_t depth,const uint8_t * input,size_t inputRowPitch,size_t inputDepthPitch,uint8_t * output,size_t outputRowPitch,size_t outputDepthPitch)689 void LoadRGBA8ToBGRA4(const ImageLoadContext &context,
690                       size_t width,
691                       size_t height,
692                       size_t depth,
693                       const uint8_t *input,
694                       size_t inputRowPitch,
695                       size_t inputDepthPitch,
696                       uint8_t *output,
697                       size_t outputRowPitch,
698                       size_t outputDepthPitch)
699 {
700     for (size_t z = 0; z < depth; z++)
701     {
702         for (size_t y = 0; y < height; y++)
703         {
704             const uint32_t *source =
705                 priv::OffsetDataPointer<uint32_t>(input, y, z, inputRowPitch, inputDepthPitch);
706             uint16_t *dest =
707                 priv::OffsetDataPointer<uint16_t>(output, y, z, outputRowPitch, outputDepthPitch);
708             for (size_t x = 0; x < width; x++)
709             {
710                 uint32_t rgba8 = source[x];
711                 auto r4        = static_cast<uint16_t>((rgba8 & 0x000000FF) >> 4);
712                 auto g4        = static_cast<uint16_t>((rgba8 & 0x0000FF00) >> 12);
713                 auto b4        = static_cast<uint16_t>((rgba8 & 0x00FF0000) >> 20);
714                 auto a4        = static_cast<uint16_t>((rgba8 & 0xFF000000) >> 28);
715                 dest[x]        = (a4 << 12) | (r4 << 8) | (g4 << 4) | b4;
716             }
717         }
718     }
719 }
720 
LoadRGBA8ToRGBA4(const ImageLoadContext & context,size_t width,size_t height,size_t depth,const uint8_t * input,size_t inputRowPitch,size_t inputDepthPitch,uint8_t * output,size_t outputRowPitch,size_t outputDepthPitch)721 void LoadRGBA8ToRGBA4(const ImageLoadContext &context,
722                       size_t width,
723                       size_t height,
724                       size_t depth,
725                       const uint8_t *input,
726                       size_t inputRowPitch,
727                       size_t inputDepthPitch,
728                       uint8_t *output,
729                       size_t outputRowPitch,
730                       size_t outputDepthPitch)
731 {
732     for (size_t z = 0; z < depth; z++)
733     {
734         for (size_t y = 0; y < height; y++)
735         {
736             const uint32_t *source =
737                 priv::OffsetDataPointer<uint32_t>(input, y, z, inputRowPitch, inputDepthPitch);
738             uint16_t *dest =
739                 priv::OffsetDataPointer<uint16_t>(output, y, z, outputRowPitch, outputDepthPitch);
740             for (size_t x = 0; x < width; x++)
741             {
742                 uint32_t rgba8 = source[x];
743                 auto r4        = static_cast<uint16_t>((rgba8 & 0x000000FF) >> 4);
744                 auto g4        = static_cast<uint16_t>((rgba8 & 0x0000FF00) >> 12);
745                 auto b4        = static_cast<uint16_t>((rgba8 & 0x00FF0000) >> 20);
746                 auto a4        = static_cast<uint16_t>((rgba8 & 0xFF000000) >> 28);
747                 dest[x]        = (r4 << 12) | (g4 << 8) | (b4 << 4) | a4;
748             }
749         }
750     }
751 }
752 
LoadRGBA4ToARGB4(const ImageLoadContext & context,size_t width,size_t height,size_t depth,const uint8_t * input,size_t inputRowPitch,size_t inputDepthPitch,uint8_t * output,size_t outputRowPitch,size_t outputDepthPitch)753 void LoadRGBA4ToARGB4(const ImageLoadContext &context,
754                       size_t width,
755                       size_t height,
756                       size_t depth,
757                       const uint8_t *input,
758                       size_t inputRowPitch,
759                       size_t inputDepthPitch,
760                       uint8_t *output,
761                       size_t outputRowPitch,
762                       size_t outputDepthPitch)
763 {
764     for (size_t z = 0; z < depth; z++)
765     {
766         for (size_t y = 0; y < height; y++)
767         {
768             const uint16_t *source =
769                 priv::OffsetDataPointer<uint16_t>(input, y, z, inputRowPitch, inputDepthPitch);
770             uint16_t *dest =
771                 priv::OffsetDataPointer<uint16_t>(output, y, z, outputRowPitch, outputDepthPitch);
772             for (size_t x = 0; x < width; x++)
773             {
774                 dest[x] = ANGLE_ROTR16(source[x], 4);
775             }
776         }
777     }
778 }
779 
LoadRGBA4ToBGRA8(const ImageLoadContext & context,size_t width,size_t height,size_t depth,const uint8_t * input,size_t inputRowPitch,size_t inputDepthPitch,uint8_t * output,size_t outputRowPitch,size_t outputDepthPitch)780 void LoadRGBA4ToBGRA8(const ImageLoadContext &context,
781                       size_t width,
782                       size_t height,
783                       size_t depth,
784                       const uint8_t *input,
785                       size_t inputRowPitch,
786                       size_t inputDepthPitch,
787                       uint8_t *output,
788                       size_t outputRowPitch,
789                       size_t outputDepthPitch)
790 {
791     for (size_t z = 0; z < depth; z++)
792     {
793         for (size_t y = 0; y < height; y++)
794         {
795             const uint16_t *source =
796                 priv::OffsetDataPointer<uint16_t>(input, y, z, inputRowPitch, inputDepthPitch);
797             uint8_t *dest =
798                 priv::OffsetDataPointer<uint8_t>(output, y, z, outputRowPitch, outputDepthPitch);
799             for (size_t x = 0; x < width; x++)
800             {
801                 uint16_t rgba = source[x];
802                 dest[4 * x + 0] =
803                     static_cast<uint8_t>(((rgba & 0x00F0) << 0) | ((rgba & 0x00F0) >> 4));
804                 dest[4 * x + 1] =
805                     static_cast<uint8_t>(((rgba & 0x0F00) >> 4) | ((rgba & 0x0F00) >> 8));
806                 dest[4 * x + 2] =
807                     static_cast<uint8_t>(((rgba & 0xF000) >> 8) | ((rgba & 0xF000) >> 12));
808                 dest[4 * x + 3] =
809                     static_cast<uint8_t>(((rgba & 0x000F) << 4) | ((rgba & 0x000F) >> 0));
810             }
811         }
812     }
813 }
814 
LoadRGBA4ToRGBA8(const ImageLoadContext & context,size_t width,size_t height,size_t depth,const uint8_t * input,size_t inputRowPitch,size_t inputDepthPitch,uint8_t * output,size_t outputRowPitch,size_t outputDepthPitch)815 void LoadRGBA4ToRGBA8(const ImageLoadContext &context,
816                       size_t width,
817                       size_t height,
818                       size_t depth,
819                       const uint8_t *input,
820                       size_t inputRowPitch,
821                       size_t inputDepthPitch,
822                       uint8_t *output,
823                       size_t outputRowPitch,
824                       size_t outputDepthPitch)
825 {
826     for (size_t z = 0; z < depth; z++)
827     {
828         for (size_t y = 0; y < height; y++)
829         {
830             const uint16_t *source =
831                 priv::OffsetDataPointer<uint16_t>(input, y, z, inputRowPitch, inputDepthPitch);
832             uint8_t *dest =
833                 priv::OffsetDataPointer<uint8_t>(output, y, z, outputRowPitch, outputDepthPitch);
834             for (size_t x = 0; x < width; x++)
835             {
836                 uint16_t rgba = source[x];
837                 dest[4 * x + 0] =
838                     static_cast<uint8_t>(((rgba & 0xF000) >> 8) | ((rgba & 0xF000) >> 12));
839                 dest[4 * x + 1] =
840                     static_cast<uint8_t>(((rgba & 0x0F00) >> 4) | ((rgba & 0x0F00) >> 8));
841                 dest[4 * x + 2] =
842                     static_cast<uint8_t>(((rgba & 0x00F0) << 0) | ((rgba & 0x00F0) >> 4));
843                 dest[4 * x + 3] =
844                     static_cast<uint8_t>(((rgba & 0x000F) << 4) | ((rgba & 0x000F) >> 0));
845             }
846         }
847     }
848 }
849 
LoadBGRA4ToBGRA8(const ImageLoadContext & context,size_t width,size_t height,size_t depth,const uint8_t * input,size_t inputRowPitch,size_t inputDepthPitch,uint8_t * output,size_t outputRowPitch,size_t outputDepthPitch)850 void LoadBGRA4ToBGRA8(const ImageLoadContext &context,
851                       size_t width,
852                       size_t height,
853                       size_t depth,
854                       const uint8_t *input,
855                       size_t inputRowPitch,
856                       size_t inputDepthPitch,
857                       uint8_t *output,
858                       size_t outputRowPitch,
859                       size_t outputDepthPitch)
860 {
861     for (size_t z = 0; z < depth; z++)
862     {
863         for (size_t y = 0; y < height; y++)
864         {
865             const uint16_t *source =
866                 priv::OffsetDataPointer<uint16_t>(input, y, z, inputRowPitch, inputDepthPitch);
867             uint8_t *dest =
868                 priv::OffsetDataPointer<uint8_t>(output, y, z, outputRowPitch, outputDepthPitch);
869             for (size_t x = 0; x < width; x++)
870             {
871                 uint16_t bgra = source[x];
872                 dest[4 * x + 0] =
873                     static_cast<uint8_t>(((bgra & 0xF000) >> 8) | ((bgra & 0xF000) >> 12));
874                 dest[4 * x + 1] =
875                     static_cast<uint8_t>(((bgra & 0x0F00) >> 4) | ((bgra & 0x0F00) >> 8));
876                 dest[4 * x + 2] =
877                     static_cast<uint8_t>(((bgra & 0x00F0) << 0) | ((bgra & 0x00F0) >> 4));
878                 dest[4 * x + 3] =
879                     static_cast<uint8_t>(((bgra & 0x000F) << 4) | ((bgra & 0x000F) >> 0));
880             }
881         }
882     }
883 }
884 
LoadRGBA8ToBGR5A1(const ImageLoadContext & context,size_t width,size_t height,size_t depth,const uint8_t * input,size_t inputRowPitch,size_t inputDepthPitch,uint8_t * output,size_t outputRowPitch,size_t outputDepthPitch)885 void LoadRGBA8ToBGR5A1(const ImageLoadContext &context,
886                        size_t width,
887                        size_t height,
888                        size_t depth,
889                        const uint8_t *input,
890                        size_t inputRowPitch,
891                        size_t inputDepthPitch,
892                        uint8_t *output,
893                        size_t outputRowPitch,
894                        size_t outputDepthPitch)
895 {
896     for (size_t z = 0; z < depth; z++)
897     {
898         for (size_t y = 0; y < height; y++)
899         {
900             const uint32_t *source =
901                 priv::OffsetDataPointer<uint32_t>(input, y, z, inputRowPitch, inputDepthPitch);
902             uint16_t *dest =
903                 priv::OffsetDataPointer<uint16_t>(output, y, z, outputRowPitch, outputDepthPitch);
904             for (size_t x = 0; x < width; x++)
905             {
906                 uint32_t rgba8 = source[x];
907                 auto r5        = static_cast<uint16_t>((rgba8 & 0x000000FF) >> 3);
908                 auto g5        = static_cast<uint16_t>((rgba8 & 0x0000FF00) >> 11);
909                 auto b5        = static_cast<uint16_t>((rgba8 & 0x00FF0000) >> 19);
910                 auto a1        = static_cast<uint16_t>((rgba8 & 0xFF000000) >> 31);
911                 dest[x]        = (a1 << 15) | (r5 << 10) | (g5 << 5) | b5;
912             }
913         }
914     }
915 }
916 
LoadRGBA8ToRGB5A1(const ImageLoadContext & context,size_t width,size_t height,size_t depth,const uint8_t * input,size_t inputRowPitch,size_t inputDepthPitch,uint8_t * output,size_t outputRowPitch,size_t outputDepthPitch)917 void LoadRGBA8ToRGB5A1(const ImageLoadContext &context,
918                        size_t width,
919                        size_t height,
920                        size_t depth,
921                        const uint8_t *input,
922                        size_t inputRowPitch,
923                        size_t inputDepthPitch,
924                        uint8_t *output,
925                        size_t outputRowPitch,
926                        size_t outputDepthPitch)
927 {
928     for (size_t z = 0; z < depth; z++)
929     {
930         for (size_t y = 0; y < height; y++)
931         {
932             const uint32_t *source =
933                 priv::OffsetDataPointer<uint32_t>(input, y, z, inputRowPitch, inputDepthPitch);
934             uint16_t *dest =
935                 priv::OffsetDataPointer<uint16_t>(output, y, z, outputRowPitch, outputDepthPitch);
936             for (size_t x = 0; x < width; x++)
937             {
938                 uint32_t rgba8 = source[x];
939                 auto r5        = static_cast<uint16_t>((rgba8 & 0x000000FF) >> 3);
940                 auto g5        = static_cast<uint16_t>((rgba8 & 0x0000FF00) >> 11);
941                 auto b5        = static_cast<uint16_t>((rgba8 & 0x00FF0000) >> 19);
942                 auto a1        = static_cast<uint16_t>((rgba8 & 0xFF000000) >> 31);
943                 dest[x]        = (r5 << 11) | (g5 << 6) | (b5 << 1) | a1;
944             }
945         }
946     }
947 }
948 
LoadRGB10A2ToBGR5A1(const ImageLoadContext & context,size_t width,size_t height,size_t depth,const uint8_t * input,size_t inputRowPitch,size_t inputDepthPitch,uint8_t * output,size_t outputRowPitch,size_t outputDepthPitch)949 void LoadRGB10A2ToBGR5A1(const ImageLoadContext &context,
950                          size_t width,
951                          size_t height,
952                          size_t depth,
953                          const uint8_t *input,
954                          size_t inputRowPitch,
955                          size_t inputDepthPitch,
956                          uint8_t *output,
957                          size_t outputRowPitch,
958                          size_t outputDepthPitch)
959 {
960     for (size_t z = 0; z < depth; z++)
961     {
962         for (size_t y = 0; y < height; y++)
963         {
964             const R10G10B10A2 *source =
965                 priv::OffsetDataPointer<R10G10B10A2>(input, y, z, inputRowPitch, inputDepthPitch);
966             uint16_t *dest =
967                 priv::OffsetDataPointer<uint16_t>(output, y, z, outputRowPitch, outputDepthPitch);
968             for (size_t x = 0; x < width; x++)
969             {
970                 R10G10B10A2 rgb10a2 = source[x];
971 
972                 uint16_t r5 = static_cast<uint16_t>(rgb10a2.R >> 5u);
973                 uint16_t g5 = static_cast<uint16_t>(rgb10a2.G >> 5u);
974                 uint16_t b5 = static_cast<uint16_t>(rgb10a2.B >> 5u);
975                 uint16_t a1 = static_cast<uint16_t>(rgb10a2.A >> 1u);
976 
977                 dest[x] = (a1 << 15) | (r5 << 10) | (g5 << 5) | b5;
978             }
979         }
980     }
981 }
982 
LoadRGB10A2ToRGB5A1(const ImageLoadContext & context,size_t width,size_t height,size_t depth,const uint8_t * input,size_t inputRowPitch,size_t inputDepthPitch,uint8_t * output,size_t outputRowPitch,size_t outputDepthPitch)983 void LoadRGB10A2ToRGB5A1(const ImageLoadContext &context,
984                          size_t width,
985                          size_t height,
986                          size_t depth,
987                          const uint8_t *input,
988                          size_t inputRowPitch,
989                          size_t inputDepthPitch,
990                          uint8_t *output,
991                          size_t outputRowPitch,
992                          size_t outputDepthPitch)
993 {
994     for (size_t z = 0; z < depth; z++)
995     {
996         for (size_t y = 0; y < height; y++)
997         {
998             const R10G10B10A2 *source =
999                 priv::OffsetDataPointer<R10G10B10A2>(input, y, z, inputRowPitch, inputDepthPitch);
1000             uint16_t *dest =
1001                 priv::OffsetDataPointer<uint16_t>(output, y, z, outputRowPitch, outputDepthPitch);
1002             for (size_t x = 0; x < width; x++)
1003             {
1004                 R10G10B10A2 rgb10a2 = source[x];
1005 
1006                 uint16_t r5 = static_cast<uint16_t>(rgb10a2.R >> 5u);
1007                 uint16_t g5 = static_cast<uint16_t>(rgb10a2.G >> 5u);
1008                 uint16_t b5 = static_cast<uint16_t>(rgb10a2.B >> 5u);
1009                 uint16_t a1 = static_cast<uint16_t>(rgb10a2.A >> 1u);
1010 
1011                 dest[x] = (r5 << 11) | (g5 << 6) | (b5 << 1) | a1;
1012             }
1013         }
1014     }
1015 }
1016 
LoadRGB5A1ToA1RGB5(const ImageLoadContext & context,size_t width,size_t height,size_t depth,const uint8_t * input,size_t inputRowPitch,size_t inputDepthPitch,uint8_t * output,size_t outputRowPitch,size_t outputDepthPitch)1017 void LoadRGB5A1ToA1RGB5(const ImageLoadContext &context,
1018                         size_t width,
1019                         size_t height,
1020                         size_t depth,
1021                         const uint8_t *input,
1022                         size_t inputRowPitch,
1023                         size_t inputDepthPitch,
1024                         uint8_t *output,
1025                         size_t outputRowPitch,
1026                         size_t outputDepthPitch)
1027 {
1028     for (size_t z = 0; z < depth; z++)
1029     {
1030         for (size_t y = 0; y < height; y++)
1031         {
1032             const uint16_t *source =
1033                 priv::OffsetDataPointer<uint16_t>(input, y, z, inputRowPitch, inputDepthPitch);
1034             uint16_t *dest =
1035                 priv::OffsetDataPointer<uint16_t>(output, y, z, outputRowPitch, outputDepthPitch);
1036             for (size_t x = 0; x < width; x++)
1037             {
1038                 dest[x] = ANGLE_ROTR16(source[x], 1);
1039             }
1040         }
1041     }
1042 }
1043 
LoadRGB5A1ToBGR5A1(const ImageLoadContext & context,size_t width,size_t height,size_t depth,const uint8_t * input,size_t inputRowPitch,size_t inputDepthPitch,uint8_t * output,size_t outputRowPitch,size_t outputDepthPitch)1044 void LoadRGB5A1ToBGR5A1(const ImageLoadContext &context,
1045                         size_t width,
1046                         size_t height,
1047                         size_t depth,
1048                         const uint8_t *input,
1049                         size_t inputRowPitch,
1050                         size_t inputDepthPitch,
1051                         uint8_t *output,
1052                         size_t outputRowPitch,
1053                         size_t outputDepthPitch)
1054 {
1055     for (size_t z = 0; z < depth; z++)
1056     {
1057         for (size_t y = 0; y < height; y++)
1058         {
1059             const uint16_t *source =
1060                 priv::OffsetDataPointer<uint16_t>(input, y, z, inputRowPitch, inputDepthPitch);
1061             uint16_t *dest =
1062                 priv::OffsetDataPointer<uint16_t>(output, y, z, outputRowPitch, outputDepthPitch);
1063             for (size_t x = 0; x < width; x++)
1064             {
1065                 uint16_t rgba = source[x];
1066                 auto r5       = static_cast<uint16_t>((rgba & 0xF800) >> 11);
1067                 auto g5       = static_cast<uint16_t>((rgba & 0x07c0) >> 6);
1068                 auto b5       = static_cast<uint16_t>((rgba & 0x003e) >> 1);
1069                 auto a1       = static_cast<uint16_t>((rgba & 0x0001));
1070                 dest[x]       = (b5 << 11) | (g5 << 6) | (r5 << 1) | a1;
1071             }
1072         }
1073     }
1074 }
1075 
LoadRGB5A1ToBGRA8(const ImageLoadContext & context,size_t width,size_t height,size_t depth,const uint8_t * input,size_t inputRowPitch,size_t inputDepthPitch,uint8_t * output,size_t outputRowPitch,size_t outputDepthPitch)1076 void LoadRGB5A1ToBGRA8(const ImageLoadContext &context,
1077                        size_t width,
1078                        size_t height,
1079                        size_t depth,
1080                        const uint8_t *input,
1081                        size_t inputRowPitch,
1082                        size_t inputDepthPitch,
1083                        uint8_t *output,
1084                        size_t outputRowPitch,
1085                        size_t outputDepthPitch)
1086 {
1087     for (size_t z = 0; z < depth; z++)
1088     {
1089         for (size_t y = 0; y < height; y++)
1090         {
1091             const uint16_t *source =
1092                 priv::OffsetDataPointer<uint16_t>(input, y, z, inputRowPitch, inputDepthPitch);
1093             uint8_t *dest =
1094                 priv::OffsetDataPointer<uint8_t>(output, y, z, outputRowPitch, outputDepthPitch);
1095             for (size_t x = 0; x < width; x++)
1096             {
1097                 uint16_t rgba = source[x];
1098                 dest[4 * x + 0] =
1099                     static_cast<uint8_t>(((rgba & 0x003E) << 2) | ((rgba & 0x003E) >> 3));
1100                 dest[4 * x + 1] =
1101                     static_cast<uint8_t>(((rgba & 0x07C0) >> 3) | ((rgba & 0x07C0) >> 8));
1102                 dest[4 * x + 2] =
1103                     static_cast<uint8_t>(((rgba & 0xF800) >> 8) | ((rgba & 0xF800) >> 13));
1104                 dest[4 * x + 3] = static_cast<uint8_t>((rgba & 0x0001) ? 0xFF : 0);
1105             }
1106         }
1107     }
1108 }
1109 
LoadRGB5A1ToRGBA8(const ImageLoadContext & context,size_t width,size_t height,size_t depth,const uint8_t * input,size_t inputRowPitch,size_t inputDepthPitch,uint8_t * output,size_t outputRowPitch,size_t outputDepthPitch)1110 void LoadRGB5A1ToRGBA8(const ImageLoadContext &context,
1111                        size_t width,
1112                        size_t height,
1113                        size_t depth,
1114                        const uint8_t *input,
1115                        size_t inputRowPitch,
1116                        size_t inputDepthPitch,
1117                        uint8_t *output,
1118                        size_t outputRowPitch,
1119                        size_t outputDepthPitch)
1120 {
1121     for (size_t z = 0; z < depth; z++)
1122     {
1123         for (size_t y = 0; y < height; y++)
1124         {
1125             const uint16_t *source =
1126                 priv::OffsetDataPointer<uint16_t>(input, y, z, inputRowPitch, inputDepthPitch);
1127             uint8_t *dest =
1128                 priv::OffsetDataPointer<uint8_t>(output, y, z, outputRowPitch, outputDepthPitch);
1129             for (size_t x = 0; x < width; x++)
1130             {
1131                 uint16_t rgba = source[x];
1132                 dest[4 * x + 0] =
1133                     static_cast<uint8_t>(((rgba & 0xF800) >> 8) | ((rgba & 0xF800) >> 13));
1134                 dest[4 * x + 1] =
1135                     static_cast<uint8_t>(((rgba & 0x07C0) >> 3) | ((rgba & 0x07C0) >> 8));
1136                 dest[4 * x + 2] =
1137                     static_cast<uint8_t>(((rgba & 0x003E) << 2) | ((rgba & 0x003E) >> 3));
1138                 dest[4 * x + 3] = static_cast<uint8_t>((rgba & 0x0001) ? 0xFF : 0);
1139             }
1140         }
1141     }
1142 }
1143 
LoadBGR5A1ToBGRA8(const ImageLoadContext & context,size_t width,size_t height,size_t depth,const uint8_t * input,size_t inputRowPitch,size_t inputDepthPitch,uint8_t * output,size_t outputRowPitch,size_t outputDepthPitch)1144 void LoadBGR5A1ToBGRA8(const ImageLoadContext &context,
1145                        size_t width,
1146                        size_t height,
1147                        size_t depth,
1148                        const uint8_t *input,
1149                        size_t inputRowPitch,
1150                        size_t inputDepthPitch,
1151                        uint8_t *output,
1152                        size_t outputRowPitch,
1153                        size_t outputDepthPitch)
1154 {
1155     for (size_t z = 0; z < depth; z++)
1156     {
1157         for (size_t y = 0; y < height; y++)
1158         {
1159             const uint16_t *source =
1160                 priv::OffsetDataPointer<uint16_t>(input, y, z, inputRowPitch, inputDepthPitch);
1161             uint8_t *dest =
1162                 priv::OffsetDataPointer<uint8_t>(output, y, z, outputRowPitch, outputDepthPitch);
1163             for (size_t x = 0; x < width; x++)
1164             {
1165                 uint16_t bgra = source[x];
1166                 dest[4 * x + 0] =
1167                     static_cast<uint8_t>(((bgra & 0xF800) >> 8) | ((bgra & 0xF800) >> 13));
1168                 dest[4 * x + 1] =
1169                     static_cast<uint8_t>(((bgra & 0x07C0) >> 3) | ((bgra & 0x07C0) >> 8));
1170                 dest[4 * x + 2] =
1171                     static_cast<uint8_t>(((bgra & 0x003E) << 2) | ((bgra & 0x003E) >> 3));
1172                 dest[4 * x + 3] = static_cast<uint8_t>((bgra & 0x0001) ? 0xFF : 0);
1173             }
1174         }
1175     }
1176 }
1177 
LoadRGB10A2ToRGBA8(const ImageLoadContext & context,size_t width,size_t height,size_t depth,const uint8_t * input,size_t inputRowPitch,size_t inputDepthPitch,uint8_t * output,size_t outputRowPitch,size_t outputDepthPitch)1178 void LoadRGB10A2ToRGBA8(const ImageLoadContext &context,
1179                         size_t width,
1180                         size_t height,
1181                         size_t depth,
1182                         const uint8_t *input,
1183                         size_t inputRowPitch,
1184                         size_t inputDepthPitch,
1185                         uint8_t *output,
1186                         size_t outputRowPitch,
1187                         size_t outputDepthPitch)
1188 {
1189     for (size_t z = 0; z < depth; z++)
1190     {
1191         for (size_t y = 0; y < height; y++)
1192         {
1193             const uint32_t *source =
1194                 priv::OffsetDataPointer<uint32_t>(input, y, z, inputRowPitch, inputDepthPitch);
1195             uint8_t *dest =
1196                 priv::OffsetDataPointer<uint8_t>(output, y, z, outputRowPitch, outputDepthPitch);
1197             for (size_t x = 0; x < width; x++)
1198             {
1199                 uint32_t rgba   = source[x];
1200                 dest[4 * x + 0] = static_cast<uint8_t>((rgba & 0x000003FF) >> 2);
1201                 dest[4 * x + 1] = static_cast<uint8_t>((rgba & 0x000FFC00) >> 12);
1202                 dest[4 * x + 2] = static_cast<uint8_t>((rgba & 0x3FF00000) >> 22);
1203                 dest[4 * x + 3] = static_cast<uint8_t>(((rgba & 0xC0000000) >> 30) * 0x55);
1204             }
1205         }
1206     }
1207 }
1208 
LoadRGB10A2ToRGB10X2(const ImageLoadContext & context,size_t width,size_t height,size_t depth,const uint8_t * input,size_t inputRowPitch,size_t inputDepthPitch,uint8_t * output,size_t outputRowPitch,size_t outputDepthPitch)1209 void LoadRGB10A2ToRGB10X2(const ImageLoadContext &context,
1210                           size_t width,
1211                           size_t height,
1212                           size_t depth,
1213                           const uint8_t *input,
1214                           size_t inputRowPitch,
1215                           size_t inputDepthPitch,
1216                           uint8_t *output,
1217                           size_t outputRowPitch,
1218                           size_t outputDepthPitch)
1219 {
1220     for (size_t z = 0; z < depth; z++)
1221     {
1222         for (size_t y = 0; y < height; y++)
1223         {
1224             const uint32_t *source =
1225                 priv::OffsetDataPointer<uint32_t>(input, y, z, inputRowPitch, inputDepthPitch);
1226             uint32_t *dest =
1227                 priv::OffsetDataPointer<uint32_t>(output, y, z, outputRowPitch, outputDepthPitch);
1228             for (size_t x = 0; x < width; x++)
1229             {
1230                 dest[x] = source[x] | 0xC0000000;
1231             }
1232         }
1233     }
1234 }
1235 
LoadRGB16FToRGB9E5(const ImageLoadContext & context,size_t width,size_t height,size_t depth,const uint8_t * input,size_t inputRowPitch,size_t inputDepthPitch,uint8_t * output,size_t outputRowPitch,size_t outputDepthPitch)1236 void LoadRGB16FToRGB9E5(const ImageLoadContext &context,
1237                         size_t width,
1238                         size_t height,
1239                         size_t depth,
1240                         const uint8_t *input,
1241                         size_t inputRowPitch,
1242                         size_t inputDepthPitch,
1243                         uint8_t *output,
1244                         size_t outputRowPitch,
1245                         size_t outputDepthPitch)
1246 {
1247     for (size_t z = 0; z < depth; z++)
1248     {
1249         for (size_t y = 0; y < height; y++)
1250         {
1251             const uint16_t *source =
1252                 priv::OffsetDataPointer<uint16_t>(input, y, z, inputRowPitch, inputDepthPitch);
1253             uint32_t *dest =
1254                 priv::OffsetDataPointer<uint32_t>(output, y, z, outputRowPitch, outputDepthPitch);
1255             for (size_t x = 0; x < width; x++)
1256             {
1257                 dest[x] = gl::convertRGBFloatsTo999E5(gl::float16ToFloat32(source[x * 3 + 0]),
1258                                                       gl::float16ToFloat32(source[x * 3 + 1]),
1259                                                       gl::float16ToFloat32(source[x * 3 + 2]));
1260             }
1261         }
1262     }
1263 }
1264 
LoadRGB32FToRGB9E5(const ImageLoadContext & context,size_t width,size_t height,size_t depth,const uint8_t * input,size_t inputRowPitch,size_t inputDepthPitch,uint8_t * output,size_t outputRowPitch,size_t outputDepthPitch)1265 void LoadRGB32FToRGB9E5(const ImageLoadContext &context,
1266                         size_t width,
1267                         size_t height,
1268                         size_t depth,
1269                         const uint8_t *input,
1270                         size_t inputRowPitch,
1271                         size_t inputDepthPitch,
1272                         uint8_t *output,
1273                         size_t outputRowPitch,
1274                         size_t outputDepthPitch)
1275 {
1276     for (size_t z = 0; z < depth; z++)
1277     {
1278         for (size_t y = 0; y < height; y++)
1279         {
1280             const float *source =
1281                 priv::OffsetDataPointer<float>(input, y, z, inputRowPitch, inputDepthPitch);
1282             uint32_t *dest =
1283                 priv::OffsetDataPointer<uint32_t>(output, y, z, outputRowPitch, outputDepthPitch);
1284             for (size_t x = 0; x < width; x++)
1285             {
1286                 dest[x] = gl::convertRGBFloatsTo999E5(source[x * 3 + 0], source[x * 3 + 1],
1287                                                       source[x * 3 + 2]);
1288             }
1289         }
1290     }
1291 }
1292 
LoadRGB16FToRG11B10F(const ImageLoadContext & context,size_t width,size_t height,size_t depth,const uint8_t * input,size_t inputRowPitch,size_t inputDepthPitch,uint8_t * output,size_t outputRowPitch,size_t outputDepthPitch)1293 void LoadRGB16FToRG11B10F(const ImageLoadContext &context,
1294                           size_t width,
1295                           size_t height,
1296                           size_t depth,
1297                           const uint8_t *input,
1298                           size_t inputRowPitch,
1299                           size_t inputDepthPitch,
1300                           uint8_t *output,
1301                           size_t outputRowPitch,
1302                           size_t outputDepthPitch)
1303 {
1304     for (size_t z = 0; z < depth; z++)
1305     {
1306         for (size_t y = 0; y < height; y++)
1307         {
1308             const uint16_t *source =
1309                 priv::OffsetDataPointer<uint16_t>(input, y, z, inputRowPitch, inputDepthPitch);
1310             uint32_t *dest =
1311                 priv::OffsetDataPointer<uint32_t>(output, y, z, outputRowPitch, outputDepthPitch);
1312             for (size_t x = 0; x < width; x++)
1313             {
1314                 dest[x] = (gl::float32ToFloat11(gl::float16ToFloat32(source[x * 3 + 0])) << 0) |
1315                           (gl::float32ToFloat11(gl::float16ToFloat32(source[x * 3 + 1])) << 11) |
1316                           (gl::float32ToFloat10(gl::float16ToFloat32(source[x * 3 + 2])) << 22);
1317             }
1318         }
1319     }
1320 }
1321 
LoadRGB32FToRG11B10F(const ImageLoadContext & context,size_t width,size_t height,size_t depth,const uint8_t * input,size_t inputRowPitch,size_t inputDepthPitch,uint8_t * output,size_t outputRowPitch,size_t outputDepthPitch)1322 void LoadRGB32FToRG11B10F(const ImageLoadContext &context,
1323                           size_t width,
1324                           size_t height,
1325                           size_t depth,
1326                           const uint8_t *input,
1327                           size_t inputRowPitch,
1328                           size_t inputDepthPitch,
1329                           uint8_t *output,
1330                           size_t outputRowPitch,
1331                           size_t outputDepthPitch)
1332 {
1333     for (size_t z = 0; z < depth; z++)
1334     {
1335         for (size_t y = 0; y < height; y++)
1336         {
1337             const float *source =
1338                 priv::OffsetDataPointer<float>(input, y, z, inputRowPitch, inputDepthPitch);
1339             uint32_t *dest =
1340                 priv::OffsetDataPointer<uint32_t>(output, y, z, outputRowPitch, outputDepthPitch);
1341             for (size_t x = 0; x < width; x++)
1342             {
1343                 dest[x] = (gl::float32ToFloat11(source[x * 3 + 0]) << 0) |
1344                           (gl::float32ToFloat11(source[x * 3 + 1]) << 11) |
1345                           (gl::float32ToFloat10(source[x * 3 + 2]) << 22);
1346             }
1347         }
1348     }
1349 }
1350 
LoadD24S8ToS8D24(const ImageLoadContext & context,size_t width,size_t height,size_t depth,const uint8_t * input,size_t inputRowPitch,size_t inputDepthPitch,uint8_t * output,size_t outputRowPitch,size_t outputDepthPitch)1351 void LoadD24S8ToS8D24(const ImageLoadContext &context,
1352                       size_t width,
1353                       size_t height,
1354                       size_t depth,
1355                       const uint8_t *input,
1356                       size_t inputRowPitch,
1357                       size_t inputDepthPitch,
1358                       uint8_t *output,
1359                       size_t outputRowPitch,
1360                       size_t outputDepthPitch)
1361 {
1362     for (size_t z = 0; z < depth; z++)
1363     {
1364         for (size_t y = 0; y < height; y++)
1365         {
1366             const uint32_t *source =
1367                 priv::OffsetDataPointer<uint32_t>(input, y, z, inputRowPitch, inputDepthPitch);
1368             uint32_t *dest =
1369                 priv::OffsetDataPointer<uint32_t>(output, y, z, outputRowPitch, outputDepthPitch);
1370             for (size_t x = 0; x < width; x++)
1371             {
1372                 dest[x] = ANGLE_ROTL(source[x], 24);
1373             }
1374         }
1375     }
1376 }
1377 
LoadD24S8ToD32FS8X24(const ImageLoadContext & context,size_t width,size_t height,size_t depth,const uint8_t * input,size_t inputRowPitch,size_t inputDepthPitch,uint8_t * output,size_t outputRowPitch,size_t outputDepthPitch)1378 void LoadD24S8ToD32FS8X24(const ImageLoadContext &context,
1379                           size_t width,
1380                           size_t height,
1381                           size_t depth,
1382                           const uint8_t *input,
1383                           size_t inputRowPitch,
1384                           size_t inputDepthPitch,
1385                           uint8_t *output,
1386                           size_t outputRowPitch,
1387                           size_t outputDepthPitch)
1388 {
1389     for (size_t z = 0; z < depth; z++)
1390     {
1391         for (size_t y = 0; y < height; y++)
1392         {
1393             const uint32_t *source =
1394                 priv::OffsetDataPointer<uint32_t>(input, y, z, inputRowPitch, inputDepthPitch);
1395             float *destDepth =
1396                 priv::OffsetDataPointer<float>(output, y, z, outputRowPitch, outputDepthPitch);
1397             uint32_t *destStencil =
1398                 priv::OffsetDataPointer<uint32_t>(output, y, z, outputRowPitch, outputDepthPitch) +
1399                 1;
1400             for (size_t x = 0; x < width; x++)
1401             {
1402                 destDepth[x * 2]   = (source[x] >> 8) / static_cast<float>(0xFFFFFF);
1403                 destStencil[x * 2] = source[x] & 0xFF;
1404             }
1405         }
1406     }
1407 }
1408 
LoadD24S8ToD32F(const ImageLoadContext & context,size_t width,size_t height,size_t depth,const uint8_t * input,size_t inputRowPitch,size_t inputDepthPitch,uint8_t * output,size_t outputRowPitch,size_t outputDepthPitch)1409 void LoadD24S8ToD32F(const ImageLoadContext &context,
1410                      size_t width,
1411                      size_t height,
1412                      size_t depth,
1413                      const uint8_t *input,
1414                      size_t inputRowPitch,
1415                      size_t inputDepthPitch,
1416                      uint8_t *output,
1417                      size_t outputRowPitch,
1418                      size_t outputDepthPitch)
1419 {
1420     for (size_t z = 0; z < depth; z++)
1421     {
1422         for (size_t y = 0; y < height; y++)
1423         {
1424             const uint32_t *source =
1425                 priv::OffsetDataPointer<uint32_t>(input, y, z, inputRowPitch, inputDepthPitch);
1426             float *destDepth =
1427                 priv::OffsetDataPointer<float>(output, y, z, outputRowPitch, outputDepthPitch);
1428             for (size_t x = 0; x < width; x++)
1429             {
1430                 destDepth[x] = (source[x] >> 8) / static_cast<float>(0xFFFFFF);
1431             }
1432         }
1433     }
1434 }
1435 
LoadD32ToD32FX32(const ImageLoadContext & context,size_t width,size_t height,size_t depth,const uint8_t * input,size_t inputRowPitch,size_t inputDepthPitch,uint8_t * output,size_t outputRowPitch,size_t outputDepthPitch)1436 void LoadD32ToD32FX32(const ImageLoadContext &context,
1437                       size_t width,
1438                       size_t height,
1439                       size_t depth,
1440                       const uint8_t *input,
1441                       size_t inputRowPitch,
1442                       size_t inputDepthPitch,
1443                       uint8_t *output,
1444                       size_t outputRowPitch,
1445                       size_t outputDepthPitch)
1446 {
1447     for (size_t z = 0; z < depth; z++)
1448     {
1449         for (size_t y = 0; y < height; y++)
1450         {
1451             const uint32_t *source =
1452                 priv::OffsetDataPointer<uint32_t>(input, y, z, inputRowPitch, inputDepthPitch);
1453             float *destDepth =
1454                 priv::OffsetDataPointer<float>(output, y, z, outputRowPitch, outputDepthPitch);
1455             for (size_t x = 0; x < width; x++)
1456             {
1457                 destDepth[x * 2] = source[x] / static_cast<float>(0xFFFFFFFF);
1458             }
1459         }
1460     }
1461 }
1462 
LoadD32ToD32F(const ImageLoadContext & context,size_t width,size_t height,size_t depth,const uint8_t * input,size_t inputRowPitch,size_t inputDepthPitch,uint8_t * output,size_t outputRowPitch,size_t outputDepthPitch)1463 void LoadD32ToD32F(const ImageLoadContext &context,
1464                    size_t width,
1465                    size_t height,
1466                    size_t depth,
1467                    const uint8_t *input,
1468                    size_t inputRowPitch,
1469                    size_t inputDepthPitch,
1470                    uint8_t *output,
1471                    size_t outputRowPitch,
1472                    size_t outputDepthPitch)
1473 {
1474     for (size_t z = 0; z < depth; z++)
1475     {
1476         for (size_t y = 0; y < height; y++)
1477         {
1478             const uint32_t *source =
1479                 priv::OffsetDataPointer<uint32_t>(input, y, z, inputRowPitch, inputDepthPitch);
1480             float *destDepth =
1481                 priv::OffsetDataPointer<float>(output, y, z, outputRowPitch, outputDepthPitch);
1482             for (size_t x = 0; x < width; x++)
1483             {
1484                 uint32_t sourcePixel = source[x];
1485                 destDepth[x]         = sourcePixel / static_cast<float>(0xFFFFFFFF);
1486             }
1487         }
1488     }
1489 }
1490 
LoadD32FToD32F(const ImageLoadContext & context,size_t width,size_t height,size_t depth,const uint8_t * input,size_t inputRowPitch,size_t inputDepthPitch,uint8_t * output,size_t outputRowPitch,size_t outputDepthPitch)1491 void LoadD32FToD32F(const ImageLoadContext &context,
1492                     size_t width,
1493                     size_t height,
1494                     size_t depth,
1495                     const uint8_t *input,
1496                     size_t inputRowPitch,
1497                     size_t inputDepthPitch,
1498                     uint8_t *output,
1499                     size_t outputRowPitch,
1500                     size_t outputDepthPitch)
1501 {
1502     for (size_t z = 0; z < depth; z++)
1503     {
1504         for (size_t y = 0; y < height; y++)
1505         {
1506             const float *source =
1507                 priv::OffsetDataPointer<float>(input, y, z, inputRowPitch, inputDepthPitch);
1508             float *dest =
1509                 priv::OffsetDataPointer<float>(output, y, z, outputRowPitch, outputDepthPitch);
1510             for (size_t x = 0; x < width; x++)
1511             {
1512                 dest[x] = gl::clamp01(source[x]);
1513             }
1514         }
1515     }
1516 }
1517 
LoadD32FS8X24ToS8D24(const ImageLoadContext & context,size_t width,size_t height,size_t depth,const uint8_t * input,size_t inputRowPitch,size_t inputDepthPitch,uint8_t * output,size_t outputRowPitch,size_t outputDepthPitch)1518 void LoadD32FS8X24ToS8D24(const ImageLoadContext &context,
1519                           size_t width,
1520                           size_t height,
1521                           size_t depth,
1522                           const uint8_t *input,
1523                           size_t inputRowPitch,
1524                           size_t inputDepthPitch,
1525                           uint8_t *output,
1526                           size_t outputRowPitch,
1527                           size_t outputDepthPitch)
1528 {
1529     for (size_t z = 0; z < depth; z++)
1530     {
1531         for (size_t y = 0; y < height; y++)
1532         {
1533             const float *sourceDepth =
1534                 priv::OffsetDataPointer<float>(input, y, z, inputRowPitch, inputDepthPitch);
1535             const uint32_t *sourceStencil =
1536                 priv::OffsetDataPointer<uint32_t>(input, y, z, inputRowPitch, inputDepthPitch) + 1;
1537             uint32_t *dest =
1538                 priv::OffsetDataPointer<uint32_t>(output, y, z, outputRowPitch, outputDepthPitch);
1539             for (size_t x = 0; x < width; x++)
1540             {
1541                 uint32_t d = static_cast<uint32_t>(gl::clamp01(sourceDepth[x * 2]) * 0xFFFFFF);
1542                 uint32_t s = sourceStencil[x * 2] << 24;
1543                 dest[x]    = d | s;
1544             }
1545         }
1546     }
1547 }
1548 
LoadX24S8ToS8(const ImageLoadContext & context,size_t width,size_t height,size_t depth,const uint8_t * input,size_t inputRowPitch,size_t inputDepthPitch,uint8_t * output,size_t outputRowPitch,size_t outputDepthPitch)1549 void LoadX24S8ToS8(const ImageLoadContext &context,
1550                    size_t width,
1551                    size_t height,
1552                    size_t depth,
1553                    const uint8_t *input,
1554                    size_t inputRowPitch,
1555                    size_t inputDepthPitch,
1556                    uint8_t *output,
1557                    size_t outputRowPitch,
1558                    size_t outputDepthPitch)
1559 {
1560     for (size_t z = 0; z < depth; z++)
1561     {
1562         for (size_t y = 0; y < height; y++)
1563         {
1564             const uint32_t *source = reinterpret_cast<const uint32_t *>(
1565                 input + (y * inputRowPitch) + (z * inputDepthPitch));
1566             uint8_t *destStencil =
1567                 reinterpret_cast<uint8_t *>(output + (y * outputRowPitch) + (z * outputDepthPitch));
1568             for (size_t x = 0; x < width; x++)
1569             {
1570                 destStencil[x] = (source[x] & 0xFF);
1571             }
1572         }
1573     }
1574 }
1575 
LoadX32S8ToS8(const ImageLoadContext & context,size_t width,size_t height,size_t depth,const uint8_t * input,size_t inputRowPitch,size_t inputDepthPitch,uint8_t * output,size_t outputRowPitch,size_t outputDepthPitch)1576 void LoadX32S8ToS8(const ImageLoadContext &context,
1577                    size_t width,
1578                    size_t height,
1579                    size_t depth,
1580                    const uint8_t *input,
1581                    size_t inputRowPitch,
1582                    size_t inputDepthPitch,
1583                    uint8_t *output,
1584                    size_t outputRowPitch,
1585                    size_t outputDepthPitch)
1586 {
1587     for (size_t z = 0; z < depth; z++)
1588     {
1589         for (size_t y = 0; y < height; y++)
1590         {
1591             const uint32_t *source = reinterpret_cast<const uint32_t *>(
1592                 input + (y * inputRowPitch) + (z * inputDepthPitch));
1593             uint8_t *destStencil =
1594                 reinterpret_cast<uint8_t *>(output + (y * outputRowPitch) + (z * outputDepthPitch));
1595             for (size_t x = 0; x < width; x++)
1596             {
1597                 destStencil[x] = (source[(x * 2) + 1] & 0xFF);
1598             }
1599         }
1600     }
1601 }
1602 
LoadD32FS8X24ToD32F(const ImageLoadContext & context,size_t width,size_t height,size_t depth,const uint8_t * input,size_t inputRowPitch,size_t inputDepthPitch,uint8_t * output,size_t outputRowPitch,size_t outputDepthPitch)1603 void LoadD32FS8X24ToD32F(const ImageLoadContext &context,
1604                          size_t width,
1605                          size_t height,
1606                          size_t depth,
1607                          const uint8_t *input,
1608                          size_t inputRowPitch,
1609                          size_t inputDepthPitch,
1610                          uint8_t *output,
1611                          size_t outputRowPitch,
1612                          size_t outputDepthPitch)
1613 {
1614     for (size_t z = 0; z < depth; z++)
1615     {
1616         for (size_t y = 0; y < height; y++)
1617         {
1618             const float *sourceDepth =
1619                 priv::OffsetDataPointer<float>(input, y, z, inputRowPitch, inputDepthPitch);
1620             float *destDepth =
1621                 priv::OffsetDataPointer<float>(output, y, z, outputRowPitch, outputDepthPitch);
1622             for (size_t x = 0; x < width; x++)
1623             {
1624                 destDepth[x] = gl::clamp01(sourceDepth[x * 2]);
1625             }
1626         }
1627     }
1628 }
1629 
LoadD32FS8X24ToD32FS8X24(const ImageLoadContext & context,size_t width,size_t height,size_t depth,const uint8_t * input,size_t inputRowPitch,size_t inputDepthPitch,uint8_t * output,size_t outputRowPitch,size_t outputDepthPitch)1630 void LoadD32FS8X24ToD32FS8X24(const ImageLoadContext &context,
1631                               size_t width,
1632                               size_t height,
1633                               size_t depth,
1634                               const uint8_t *input,
1635                               size_t inputRowPitch,
1636                               size_t inputDepthPitch,
1637                               uint8_t *output,
1638                               size_t outputRowPitch,
1639                               size_t outputDepthPitch)
1640 {
1641     for (size_t z = 0; z < depth; z++)
1642     {
1643         for (size_t y = 0; y < height; y++)
1644         {
1645             const float *sourceDepth =
1646                 priv::OffsetDataPointer<float>(input, y, z, inputRowPitch, inputDepthPitch);
1647             const uint32_t *sourceStencil =
1648                 priv::OffsetDataPointer<uint32_t>(input, y, z, inputRowPitch, inputDepthPitch) + 1;
1649             float *destDepth =
1650                 priv::OffsetDataPointer<float>(output, y, z, outputRowPitch, outputDepthPitch);
1651             uint32_t *destStencil =
1652                 priv::OffsetDataPointer<uint32_t>(output, y, z, outputRowPitch, outputDepthPitch) +
1653                 1;
1654             for (size_t x = 0; x < width; x++)
1655             {
1656                 destDepth[x * 2]   = gl::clamp01(sourceDepth[x * 2]);
1657                 destStencil[x * 2] = sourceStencil[x * 2] & 0xFF;
1658             }
1659         }
1660     }
1661 }
1662 
LoadRGB32FToRGBA16F(const ImageLoadContext & context,size_t width,size_t height,size_t depth,const uint8_t * input,size_t inputRowPitch,size_t inputDepthPitch,uint8_t * output,size_t outputRowPitch,size_t outputDepthPitch)1663 void LoadRGB32FToRGBA16F(const ImageLoadContext &context,
1664                          size_t width,
1665                          size_t height,
1666                          size_t depth,
1667                          const uint8_t *input,
1668                          size_t inputRowPitch,
1669                          size_t inputDepthPitch,
1670                          uint8_t *output,
1671                          size_t outputRowPitch,
1672                          size_t outputDepthPitch)
1673 {
1674     for (size_t z = 0; z < depth; z++)
1675     {
1676         for (size_t y = 0; y < height; y++)
1677         {
1678             const float *source =
1679                 priv::OffsetDataPointer<float>(input, y, z, inputRowPitch, inputDepthPitch);
1680             uint16_t *dest =
1681                 priv::OffsetDataPointer<uint16_t>(output, y, z, outputRowPitch, outputDepthPitch);
1682             for (size_t x = 0; x < width; x++)
1683             {
1684                 dest[x * 4 + 0] = gl::float32ToFloat16(source[x * 3 + 0]);
1685                 dest[x * 4 + 1] = gl::float32ToFloat16(source[x * 3 + 1]);
1686                 dest[x * 4 + 2] = gl::float32ToFloat16(source[x * 3 + 2]);
1687                 dest[x * 4 + 3] = gl::Float16One;
1688             }
1689         }
1690     }
1691 }
1692 
LoadRGB32FToRGB16F(const ImageLoadContext & context,size_t width,size_t height,size_t depth,const uint8_t * input,size_t inputRowPitch,size_t inputDepthPitch,uint8_t * output,size_t outputRowPitch,size_t outputDepthPitch)1693 void LoadRGB32FToRGB16F(const ImageLoadContext &context,
1694                         size_t width,
1695                         size_t height,
1696                         size_t depth,
1697                         const uint8_t *input,
1698                         size_t inputRowPitch,
1699                         size_t inputDepthPitch,
1700                         uint8_t *output,
1701                         size_t outputRowPitch,
1702                         size_t outputDepthPitch)
1703 {
1704     for (size_t z = 0; z < depth; z++)
1705     {
1706         for (size_t y = 0; y < height; y++)
1707         {
1708             const float *source =
1709                 priv::OffsetDataPointer<float>(input, y, z, inputRowPitch, inputDepthPitch);
1710             uint16_t *dest =
1711                 priv::OffsetDataPointer<uint16_t>(output, y, z, outputRowPitch, outputDepthPitch);
1712             for (size_t x = 0; x < width; x++)
1713             {
1714                 dest[x * 3 + 0] = gl::float32ToFloat16(source[x * 3 + 0]);
1715                 dest[x * 3 + 1] = gl::float32ToFloat16(source[x * 3 + 1]);
1716                 dest[x * 3 + 2] = gl::float32ToFloat16(source[x * 3 + 2]);
1717             }
1718         }
1719     }
1720 }
1721 
LoadR32ToR16(const ImageLoadContext & context,size_t width,size_t height,size_t depth,const uint8_t * input,size_t inputRowPitch,size_t inputDepthPitch,uint8_t * output,size_t outputRowPitch,size_t outputDepthPitch)1722 void LoadR32ToR16(const ImageLoadContext &context,
1723                   size_t width,
1724                   size_t height,
1725                   size_t depth,
1726                   const uint8_t *input,
1727                   size_t inputRowPitch,
1728                   size_t inputDepthPitch,
1729                   uint8_t *output,
1730                   size_t outputRowPitch,
1731                   size_t outputDepthPitch)
1732 {
1733     for (size_t z = 0; z < depth; z++)
1734     {
1735         for (size_t y = 0; y < height; y++)
1736         {
1737             const uint32_t *source =
1738                 priv::OffsetDataPointer<uint32_t>(input, y, z, inputRowPitch, inputDepthPitch);
1739             uint16_t *dest =
1740                 priv::OffsetDataPointer<uint16_t>(output, y, z, outputRowPitch, outputDepthPitch);
1741             for (size_t x = 0; x < width; x++)
1742             {
1743                 dest[x] = source[x] >> 16;
1744             }
1745         }
1746     }
1747 }
1748 
LoadD32ToX8D24(const ImageLoadContext & context,size_t width,size_t height,size_t depth,const uint8_t * input,size_t inputRowPitch,size_t inputDepthPitch,uint8_t * output,size_t outputRowPitch,size_t outputDepthPitch)1749 void LoadD32ToX8D24(const ImageLoadContext &context,
1750                     size_t width,
1751                     size_t height,
1752                     size_t depth,
1753                     const uint8_t *input,
1754                     size_t inputRowPitch,
1755                     size_t inputDepthPitch,
1756                     uint8_t *output,
1757                     size_t outputRowPitch,
1758                     size_t outputDepthPitch)
1759 {
1760     for (size_t z = 0; z < depth; z++)
1761     {
1762         for (size_t y = 0; y < height; y++)
1763         {
1764             const uint32_t *source =
1765                 priv::OffsetDataPointer<uint32_t>(input, y, z, inputRowPitch, inputDepthPitch);
1766             uint32_t *dest =
1767                 priv::OffsetDataPointer<uint32_t>(output, y, z, outputRowPitch, outputDepthPitch);
1768 
1769             for (size_t x = 0; x < width; x++)
1770             {
1771                 dest[x] = source[x] >> 8;
1772             }
1773         }
1774     }
1775 }
1776 
1777 // This conversion was added to support using a 32F depth buffer
1778 // as emulation for 16unorm depth buffer in Metal.
1779 // See https://anglebug.com/6597
LoadD16ToD32F(const ImageLoadContext & context,size_t width,size_t height,size_t depth,const uint8_t * input,size_t inputRowPitch,size_t inputDepthPitch,uint8_t * output,size_t outputRowPitch,size_t outputDepthPitch)1780 void LoadD16ToD32F(const ImageLoadContext &context,
1781                    size_t width,
1782                    size_t height,
1783                    size_t depth,
1784                    const uint8_t *input,
1785                    size_t inputRowPitch,
1786                    size_t inputDepthPitch,
1787                    uint8_t *output,
1788                    size_t outputRowPitch,
1789                    size_t outputDepthPitch)
1790 {
1791     for (size_t z = 0; z < depth; z++)
1792     {
1793         for (size_t y = 0; y < height; y++)
1794         {
1795             const uint16_t *source =
1796                 priv::OffsetDataPointer<uint16_t>(input, y, z, inputRowPitch, inputDepthPitch);
1797             float *dest =
1798                 priv::OffsetDataPointer<float>(output, y, z, outputRowPitch, outputDepthPitch);
1799             for (size_t x = 0; x < width; x++)
1800             {
1801                 dest[x] = static_cast<float>(source[x]) / 0xFFFF;
1802             }
1803         }
1804     }
1805 }
1806 
LoadS8ToS8X24(const ImageLoadContext & context,size_t width,size_t height,size_t depth,const uint8_t * input,size_t inputRowPitch,size_t inputDepthPitch,uint8_t * output,size_t outputRowPitch,size_t outputDepthPitch)1807 void LoadS8ToS8X24(const ImageLoadContext &context,
1808                    size_t width,
1809                    size_t height,
1810                    size_t depth,
1811                    const uint8_t *input,
1812                    size_t inputRowPitch,
1813                    size_t inputDepthPitch,
1814                    uint8_t *output,
1815                    size_t outputRowPitch,
1816                    size_t outputDepthPitch)
1817 {
1818     for (size_t z = 0; z < depth; z++)
1819     {
1820         for (size_t y = 0; y < height; y++)
1821         {
1822             const uint8_t *source =
1823                 priv::OffsetDataPointer<uint8_t>(input, y, z, inputRowPitch, inputDepthPitch);
1824             uint32_t *destStencil =
1825                 priv::OffsetDataPointer<uint32_t>(output, y, z, outputRowPitch, outputDepthPitch);
1826 
1827             for (size_t x = 0; x < width; x++)
1828             {
1829                 destStencil[x] = source[x] << 24;
1830             }
1831         }
1832     }
1833 }
1834 
LoadYuvToNative(const ImageLoadContext & context,size_t width,size_t height,size_t depth,const uint8_t * input,size_t inputRowPitch,size_t inputDepthPitch,uint8_t * output,size_t outputRowPitch,size_t outputDepthPitch)1835 void LoadYuvToNative(const ImageLoadContext &context,
1836                      size_t width,
1837                      size_t height,
1838                      size_t depth,
1839                      const uint8_t *input,
1840                      size_t inputRowPitch,
1841                      size_t inputDepthPitch,
1842                      uint8_t *output,
1843                      size_t outputRowPitch,
1844                      size_t outputDepthPitch)
1845 {
1846     // For YUV formats it is assumed that source has tightly packed data.
1847     memcpy(output, input, inputDepthPitch);
1848 }
1849 
1850 }  // namespace angle
1851