loadimage.inc (7982B)
1 // 2 // Copyright 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 #include "common/mathutil.h" 8 9 #include <string.h> 10 11 namespace angle 12 { 13 14 namespace priv 15 { 16 17 template <typename T> 18 inline T *OffsetDataPointer(uint8_t *data, size_t y, size_t z, size_t rowPitch, size_t depthPitch) 19 { 20 return reinterpret_cast<T*>(data + (y * rowPitch) + (z * depthPitch)); 21 } 22 23 template <typename T> 24 inline const T *OffsetDataPointer(const uint8_t *data, size_t y, size_t z, size_t rowPitch, size_t depthPitch) 25 { 26 return reinterpret_cast<const T*>(data + (y * rowPitch) + (z * depthPitch)); 27 } 28 29 } // namespace priv 30 31 template <typename type, size_t componentCount> 32 inline void LoadToNative(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 const size_t rowSize = width * sizeof(type) * componentCount; 37 const size_t layerSize = rowSize * height; 38 const size_t imageSize = layerSize * depth; 39 40 if (layerSize == inputDepthPitch && layerSize == outputDepthPitch) 41 { 42 ASSERT(rowSize == inputRowPitch && rowSize == outputRowPitch); 43 memcpy(output, input, imageSize); 44 } 45 else if (rowSize == inputRowPitch && rowSize == outputRowPitch) 46 { 47 for (size_t z = 0; z < depth; z++) 48 { 49 const type *source = priv::OffsetDataPointer<type>(input, 0, z, inputRowPitch, inputDepthPitch); 50 type *dest = priv::OffsetDataPointer<type>(output, 0, z, outputRowPitch, outputDepthPitch); 51 52 memcpy(dest, source, layerSize); 53 } 54 } 55 else 56 { 57 for (size_t z = 0; z < depth; z++) 58 { 59 for (size_t y = 0; y < height; y++) 60 { 61 const type *source = priv::OffsetDataPointer<type>(input, y, z, inputRowPitch, inputDepthPitch); 62 type *dest = priv::OffsetDataPointer<type>(output, y, z, outputRowPitch, outputDepthPitch); 63 memcpy(dest, source, width * sizeof(type) * componentCount); 64 } 65 } 66 } 67 } 68 69 template <typename type, uint32_t fourthComponentBits> 70 inline void LoadToNative3To4(size_t width, size_t height, size_t depth, 71 const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, 72 uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch) 73 { 74 const type fourthValue = gl::bitCast<type>(fourthComponentBits); 75 76 for (size_t z = 0; z < depth; z++) 77 { 78 for (size_t y = 0; y < height; y++) 79 { 80 const type *source = priv::OffsetDataPointer<type>(input, y, z, inputRowPitch, inputDepthPitch); 81 type *dest = priv::OffsetDataPointer<type>(output, y, z, outputRowPitch, outputDepthPitch); 82 for (size_t x = 0; x < width; x++) 83 { 84 memcpy(&dest[x * 4], &source[x * 3], sizeof(type) * 3); 85 dest[x * 4 + 3] = fourthValue; 86 } 87 } 88 } 89 } 90 91 template <size_t componentCount> 92 inline void Load32FTo16F(size_t width, size_t height, size_t depth, 93 const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, 94 uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch) 95 { 96 const size_t elementWidth = componentCount * width; 97 98 for (size_t z = 0; z < depth; z++) 99 { 100 for (size_t y = 0; y < height; y++) 101 { 102 const float *source = priv::OffsetDataPointer<float>(input, y, z, inputRowPitch, inputDepthPitch); 103 uint16_t *dest = priv::OffsetDataPointer<uint16_t>(output, y, z, outputRowPitch, outputDepthPitch); 104 105 for (size_t x = 0; x < elementWidth; x++) 106 { 107 dest[x] = gl::float32ToFloat16(source[x]); 108 } 109 } 110 } 111 } 112 113 template <size_t blockWidth, size_t blockHeight, size_t blockDepth, size_t blockSize> 114 inline void LoadCompressedToNative(size_t width, size_t height, size_t depth, 115 const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, 116 uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch) 117 { 118 const size_t columns = (width + (blockWidth - 1)) / blockWidth; 119 const size_t rows = (height + (blockHeight - 1)) / blockHeight; 120 const size_t layers = (depth + (blockDepth - 1)) / blockDepth; 121 122 for (size_t z = 0; z < layers; ++z) 123 { 124 for (size_t y = 0; y < rows; ++y) 125 { 126 const uint8_t *source = priv::OffsetDataPointer<uint8_t>(input, y, z, inputRowPitch, inputDepthPitch); 127 uint8_t *dest = priv::OffsetDataPointer<uint8_t>(output, y, z, outputRowPitch, outputDepthPitch); 128 memcpy(dest, source, columns * blockSize); 129 } 130 } 131 } 132 133 template <typename type, uint32_t firstBits, uint32_t secondBits, uint32_t thirdBits, uint32_t fourthBits> 134 inline void Initialize4ComponentData(size_t width, size_t height, size_t depth, 135 uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch) 136 { 137 type writeValues[4] = 138 { 139 gl::bitCast<type>(firstBits), 140 gl::bitCast<type>(secondBits), 141 gl::bitCast<type>(thirdBits), 142 gl::bitCast<type>(fourthBits), 143 }; 144 145 for (size_t z = 0; z < depth; z++) 146 { 147 for (size_t y = 0; y < height; y++) 148 { 149 type *destRow = priv::OffsetDataPointer<type>(output, y, z, outputRowPitch, outputDepthPitch); 150 for (size_t x = 0; x < width; x++) 151 { 152 type* destPixel = destRow + x * 4; 153 154 // This could potentially be optimized by generating an entire row of initialization 155 // data and copying row by row instead of pixel by pixel. 156 memcpy(destPixel, writeValues, sizeof(type) * 4); 157 } 158 } 159 } 160 } 161 162 template <size_t blockWidth, size_t blockHeight> 163 inline void LoadASTCToRGBA8(size_t width, 164 size_t height, 165 size_t depth, 166 const uint8_t *input, 167 size_t inputRowPitch, 168 size_t inputDepthPitch, 169 uint8_t *output, 170 size_t outputRowPitch, 171 size_t outputDepthPitch) 172 { 173 LoadASTCToRGBA8Inner(width, height, depth, blockWidth, blockHeight, input, inputRowPitch, 174 inputDepthPitch, output, outputRowPitch, outputDepthPitch); 175 } 176 177 template <uint32_t indexBits, uint32_t redBlueBits, uint32_t greenBits, uint32_t alphaBits> 178 inline void LoadPalettedToRGBA8(size_t width, 179 size_t height, 180 size_t depth, 181 const uint8_t *input, 182 size_t inputRowPitch, 183 size_t inputDepthPitch, 184 uint8_t *output, 185 size_t outputRowPitch, 186 size_t outputDepthPitch) 187 { 188 static_assert(indexBits == 4 || indexBits == 8); 189 static_assert(redBlueBits == 4 || redBlueBits == 5 || redBlueBits == 8); 190 static_assert(greenBits == 4 || greenBits == 5 || greenBits == 6 || greenBits == 8); 191 static_assert(alphaBits == 0 || alphaBits == 1 || alphaBits == 4 || alphaBits == 8); 192 constexpr uint32_t colorBits = 2 * redBlueBits + greenBits + alphaBits; 193 static_assert(colorBits == 16 || colorBits == 24 || colorBits == 32); 194 195 LoadPalettedToRGBA8Impl(width, height, depth, 196 indexBits, redBlueBits, greenBits, alphaBits, 197 input, inputRowPitch, inputDepthPitch, 198 output, outputRowPitch, outputDepthPitch); 199 } 200 201 } // namespace angle