1/////////////////////////////////////////////////////////////////////////////////////////////////// 2// OpenGL Image Copyright (c) 2008 - 2011 G-Truc Creation (www.g-truc.net) 3/////////////////////////////////////////////////////////////////////////////////////////////////// 4// Created : 2008-12-19 5// Updated : 2010-09-08 6// Licence : This source is under MIT License 7// File : gli/core/operation.inl 8/////////////////////////////////////////////////////////////////////////////////////////////////// 9 10#include <cstring> 11 12namespace gli 13{ 14 namespace detail 15 { 16 inline image2D duplicate(image2D const & Mipmap2D) 17 { 18 image2D Result(Mipmap2D.dimensions(), Mipmap2D.format()); 19 memcpy(Result.data(), Mipmap2D.data(), Mipmap2D.capacity()); 20 return Result; 21 } 22 23 inline image2D flip(image2D const & Mipmap2D) 24 { 25 image2D Result(Mipmap2D.dimensions(), Mipmap2D.format()); 26 27 std::size_t ValueSize = Result.value_size(); 28 glm::byte * DstPtr = Result.data(); 29 glm::byte const * const SrcPtr = Mipmap2D.data(); 30 31 for(std::size_t j = 0; j < Result.dimensions().y; ++j) 32 for(std::size_t i = 0; i < Result.dimensions().x; ++i) 33 { 34 std::size_t DstIndex = (i + j * Result.dimensions().y) * ValueSize; 35 std::size_t SrcIndex = (i + (Result.dimensions().y - j) * Result.dimensions().x) * ValueSize; 36 memcpy(DstPtr + DstIndex, SrcPtr + SrcIndex, ValueSize); 37 } 38 39 return Result; 40 } 41 42 inline image2D mirror(image2D const & Mipmap2D) 43 { 44 image2D Result(Mipmap2D.dimensions(), Mipmap2D.format()); 45 46 std::size_t ValueSize = Mipmap2D.value_size(); 47 glm::byte * DstPtr = Result.data(); 48 glm::byte const * const SrcPtr = Mipmap2D.data(); 49 50 for(std::size_t j = 0; j < Result.dimensions().y; ++j) 51 for(std::size_t i = 0; i < Result.dimensions().x; ++i) 52 { 53 std::size_t DstIndex = (i + j * Result.dimensions().x) * ValueSize; 54 std::size_t SrcIndex = ((Result.dimensions().x - i) + j * Result.dimensions().x) * ValueSize; 55 memcpy(DstPtr + DstIndex, SrcPtr + SrcIndex, ValueSize); 56 } 57 58 return Result; 59 } 60 61 inline image2D swizzle 62 ( 63 image2D const & Mipmap, 64 glm::uvec4 const & Channel 65 ) 66 { 67 image2D Result = detail::duplicate(Mipmap); 68 69 glm::byte * DataDst = Result.data(); 70 glm::byte const * const DataSrc = Mipmap.data(); 71 72 gli::texture2D::size_type CompSize = Mipmap.value_size() / Mipmap.components(); 73 gli::texture2D::size_type TexelCount = Mipmap.capacity() / Mipmap.value_size(); 74 75 for(gli::texture2D::size_type t = 0; t < TexelCount; ++t) 76 for(gli::texture2D::size_type c = 0; c < Mipmap.components(); ++c) 77 { 78 gli::texture2D::size_type IndexSrc = t * Mipmap.components() + Channel[static_cast<int>(c)]; 79 gli::texture2D::size_type IndexDst = t * Mipmap.components() + c; 80 81 memcpy(DataDst + IndexDst, DataSrc + IndexSrc, CompSize); 82 } 83 84 return Result; 85 } 86 87 inline image2D crop 88 ( 89 image2D const & Image, 90 image2D::dimensions_type const & Position, 91 image2D::dimensions_type const & Size 92 ) 93 { 94 assert((Position.x + Size.x) <= Image.dimensions().x && (Position.y + Size.y) <= Image.dimensions().y); 95 96 image2D Result(Size, Image.format()); 97 98 glm::byte* DstData = Result.data(); 99 glm::byte const * const SrcData = Image.data(); 100 101 for(std::size_t j = 0; j < Size.y; ++j) 102 { 103 std::size_t DstIndex = 0 + (0 + j) * Size.x * Image.value_size(); 104 std::size_t SrcIndex = Position.x * Image.value_size() + (Position.y + j) * Image.dimensions().x * Image.value_size(); 105 memcpy(DstData + DstIndex, SrcData + SrcIndex, Image.value_size() * Size.x); 106 } 107 108 return Result; 109 } 110 111 inline image2D copy 112 ( 113 image2D const & SrcMipmap, 114 image2D::dimensions_type const & SrcPosition, 115 image2D::dimensions_type const & SrcSize, 116 image2D & DstMipmap, 117 image2D::dimensions_type const & DstPosition 118 ) 119 { 120 assert((SrcPosition.x + SrcSize.x) <= SrcMipmap.dimensions().x && (SrcPosition.y + SrcSize.y) <= SrcMipmap.dimensions().y); 121 assert(SrcMipmap.format() == DstMipmap.format()); 122 123 glm::byte * DstData = DstMipmap.data(); 124 glm::byte const * const SrcData = SrcMipmap.data(); 125 126 std::size_t SizeX = glm::min(std::size_t(SrcSize.x + SrcPosition.x), std::size_t(DstMipmap.dimensions().x + DstPosition.x)); 127 std::size_t SizeY = glm::min(std::size_t(SrcSize.y + SrcPosition.y), std::size_t(DstMipmap.dimensions().y + DstPosition.y)); 128 129 for(std::size_t j = 0; j < SizeY; ++j) 130 { 131 std::size_t DstIndex = DstPosition.x * DstMipmap.value_size() + (DstPosition.y + j) * DstMipmap.dimensions().x * DstMipmap.value_size(); 132 std::size_t SrcIndex = SrcPosition.x * SrcMipmap.value_size() + (SrcPosition.y + j) * SrcMipmap.dimensions().x * SrcMipmap.value_size(); 133 memcpy(DstData + DstIndex, SrcData + SrcIndex, SrcMipmap.value_size() * SizeX); 134 } 135 136 return DstMipmap; 137 } 138 139 }//namespace detail 140 141 inline texture2D duplicate(texture2D const & Texture2D) 142 { 143 texture2D Result(Texture2D.levels()); 144 for(texture2D::level_type Level = 0; Level < Texture2D.levels(); ++Level) 145 Result[Level] = detail::duplicate(Texture2D[Level]); 146 return Result; 147 } 148 149 inline texture2D flip(texture2D const & Texture2D) 150 { 151 texture2D Result(Texture2D.levels()); 152 for(texture2D::level_type Level = 0; Level < Texture2D.levels(); ++Level) 153 Result[Level] = detail::flip(Texture2D[Level]); 154 return Result; 155 } 156 157 inline texture2D mirror(texture2D const & Texture2D) 158 { 159 texture2D Result(Texture2D.levels()); 160 for(texture2D::level_type Level = 0; Level < Texture2D.levels(); ++Level) 161 Result[Level] = detail::mirror(Texture2D[Level]); 162 return Result; 163 } 164 165 inline texture2D crop 166 ( 167 texture2D const & Texture2D, 168 texture2D::dimensions_type const & Position, 169 texture2D::dimensions_type const & Size 170 ) 171 { 172 texture2D Result(Texture2D.levels()); 173 for(texture2D::level_type Level = 0; Level < Texture2D.levels(); ++Level) 174 Result[Level] = detail::crop( 175 Texture2D[Level], 176 Position >> texture2D::dimensions_type(Level), 177 Size >> texture2D::dimensions_type(Level)); 178 return Result; 179 } 180 181 inline texture2D swizzle 182 ( 183 texture2D const & Texture2D, 184 glm::uvec4 const & Channel 185 ) 186 { 187 texture2D Result(Texture2D.levels()); 188 for(texture2D::level_type Level = 0; Level < Texture2D.levels(); ++Level) 189 Result[Level] = detail::swizzle(Texture2D[Level], Channel); 190 return Result; 191 } 192 193 inline texture2D copy 194 ( 195 texture2D const & SrcImage, 196 texture2D::level_type const & SrcLevel, 197 texture2D::dimensions_type const & SrcPosition, 198 texture2D::dimensions_type const & SrcDimensions, 199 texture2D & DstMipmap, 200 texture2D::level_type const & DstLevel, 201 texture2D::dimensions_type const & DstDimensions 202 ) 203 { 204 detail::copy( 205 SrcImage[SrcLevel], 206 SrcPosition, 207 SrcDimensions, 208 DstMipmap[DstLevel], 209 DstDimensions); 210 return DstMipmap; 211 } 212 213 //inline image operator+(image const & MipmapA, image const & MipmapB) 214 //{ 215 // 216 //} 217 218 //inline image operator-(image const & MipmapA, image const & MipmapB) 219 //{ 220 // 221 //} 222 223 //inline image operator*(image const & MipmapA, image const & MipmapB) 224 //{ 225 // 226 //} 227 228 //inline image operator/(image const & MipmapA, image const & MipmapB) 229 //{ 230 // 231 //} 232 233}//namespace gli 234