1 // 2 //------------------------------------------------------------ 3 // Copyright(c) 2009-2010 by Digital Media Professionals Inc. 4 // All rights reserved. 5 //------------------------------------------------------------ 6 // This source code is the confidential and proprietary 7 // of Digital Media Professionals Inc. 8 //------------------------------------------------------------ 9 // 10 11 #include "string.h" 12 13 #include "demo/Utility/demo_TextureConverter.h" 14 15 namespace demo 16 { 17 /* 18 * Definitions 19 */ 20 const u32 TEXTURE_BLOCK_SIZE = 8; 21 const u32 TEXTURE_PIXELS_IN_BLOCK = TEXTURE_BLOCK_SIZE * TEXTURE_BLOCK_SIZE; 22 #define SWAP(A, B) tmp = (A); (A) = (B); (B) = tmp 23 24 /* 25 * Type definitions 26 */ 27 28 enum TextureMode 29 { 30 TEXTURE_LINE_TO_BLOCK_MODE = 0, 31 TEXTURE_BLOCK_TO_LINE_MODE = 1 32 }; 33 34 typedef struct 35 { 36 GLenum format; 37 s32 blocksInRow; 38 s32 blocksInCol; 39 u8* src; 40 u8* dst; 41 u32 width; 42 u32 height; 43 u32 yflip; 44 u32 mode; 45 } TextureInformation; 46 47 typedef s32 (*textureConvertFunction)(TextureInformation* textureInformation); 48 49 /* 50 * Local Function Declaration 51 */ 52 static s32 GetPixelByte(const GLenum format); 53 54 static s32 ReadBlock(u32 no, u8* buf, TextureInformation* textureInformation); 55 static s32 WriteBlock(u32 no, const u8* pSrc, TextureInformation* textureInformation); 56 static s32 DeBlock(const u8* pSrc, u8* pDst, s32 blocksize, TextureInformation* textureInformation); 57 static s32 EnBlock(const u8* pSrc, u8* pDst, s32 blocksize, TextureInformation* textureInformation); 58 static s32 SwapColorComponents(TextureInformation* textureInformation); 59 60 static s32 ConvertFormat8888Function(TextureInformation* textureInformation); 61 static s32 ConvertFormat888Function(TextureInformation* textureInformation); 62 static s32 ConvertFormat88Function(TextureInformation* textureInformation); 63 static s32 ConvertFormatXXXXFunction(TextureInformation* textureInformation); 64 65 static textureConvertFunction convertFunctionArray[] = 66 { 67 ConvertFormat8888Function, /* GL_RGBA_NATIVE_DMP R8G8B8A8 */ 68 ConvertFormat888Function, /* GL_RGB_NATIVE_DMP R8G8B8 */ 69 ConvertFormat88Function, /* GL_LUMINANCE_ALPHA_NATIVE_DMP L8A8 */ 70 ConvertFormatXXXXFunction, /* else */ 71 ConvertFormatXXXXFunction, /* R5G6B5 */ 72 ConvertFormatXXXXFunction, /* R5G5B5A1 */ 73 ConvertFormatXXXXFunction, /* R4G4B4A4 */ 74 ConvertFormatXXXXFunction, /* L8 */ 75 ConvertFormatXXXXFunction /* A8 */ 76 }; 77 78 /* 79 * Export functions 80 */ 81 82 /* Block <--> Linear conversion */ ConvertGLTextureToNative(const GLenum format,const u32 width,const u32 height,void * glData,void * dmpData)83 bool ConvertGLTextureToNative(const GLenum format, const u32 width, const u32 height, 84 void* glData, void* dmpData) 85 { 86 bool yflip = true; 87 TextureMode mode = TEXTURE_LINE_TO_BLOCK_MODE; 88 89 u8 blockBuf[TEXTURE_PIXELS_IN_BLOCK * 4]; 90 TextureInformation textureInformation; 91 92 if (width & 0x00000003 || height & 0x00000003) 93 { 94 return false; 95 } 96 97 textureInformation.format = format; 98 textureInformation.width = width; 99 textureInformation.height = height; 100 textureInformation.blocksInRow = (textureInformation.width / TEXTURE_BLOCK_SIZE); 101 textureInformation.blocksInCol = (textureInformation.height / TEXTURE_BLOCK_SIZE); 102 textureInformation.src = (u8*)glData; 103 textureInformation.dst = (u8*)dmpData; 104 if ( yflip ) 105 { 106 textureInformation.yflip = 1; 107 } 108 else 109 { 110 textureInformation.yflip = 0; 111 } 112 textureInformation.mode = mode; 113 114 /* Convert color format */ 115 SwapColorComponents(&textureInformation); 116 /* for each row */ 117 for (s32 row = 0; row < textureInformation.blocksInCol; row++) 118 { 119 /* for each column */ 120 for (s32 col = 0; col < textureInformation.blocksInRow; col++) 121 { 122 /* Read one unit from source buffer. Read in source addressing and color format */ 123 ReadBlock(row * textureInformation.blocksInRow + col, blockBuf, &textureInformation); 124 /* Write one unit to destination buffer. written with converting addressing format */ 125 WriteBlock(row * textureInformation.blocksInRow + col, blockBuf, &textureInformation); 126 } 127 } 128 129 return true; 130 } 131 132 /* 133 * Local functions 134 */ GetPixelByte(const GLenum format)135 static s32 GetPixelByte(const GLenum format) 136 { 137 /* GL_RGBA_NATIVE_DMP R8G8B8A8 */ 138 if ( format == GL_RGBA_NATIVE_DMP ) 139 { 140 return 4; 141 } 142 /* GL_RGB_NATIVE_DMP R8G8B8 */ 143 else if ( format == GL_RGB_NATIVE_DMP ) 144 { 145 return 3; 146 } 147 /* GL_LUMINANCE_ALPHA_NATIVE_DMP L8A8 */ 148 else if ( format == GL_LUMINANCE_ALPHA_NATIVE_DMP ) 149 { 150 return 2; 151 } 152 else 153 { 154 NN_TLOG_("Unsupported texture format."); 155 NN_TASSERT_(0); 156 157 return 1; 158 } 159 } 160 ReadBlock(u32 no,u8 * buf,TextureInformation * textureInformation)161 static s32 ReadBlock(u32 no, u8* buf, TextureInformation* textureInformation) 162 { 163 u32 row = (no / textureInformation->blocksInRow); 164 u32 column = (no % textureInformation->blocksInRow); 165 u32 pixelByte = GetPixelByte(textureInformation->format); 166 167 /* Read src us32 */ 168 if (textureInformation->mode == TEXTURE_BLOCK_TO_LINE_MODE) 169 { 170 /* Get source buffer pointer */ 171 const u8* pSrc = textureInformation->src + 172 no * pixelByte * TEXTURE_PIXELS_IN_BLOCK; 173 174 /* read uint image from block format buffer */ 175 memcpy(buf, pSrc, (TEXTURE_PIXELS_IN_BLOCK * pixelByte) ); 176 } 177 else // if (mode == L2B) 178 { 179 /* Get source buffer pointer */ 180 const u8* pSrc = textureInformation->src + 181 (row * TEXTURE_PIXELS_IN_BLOCK * pixelByte * textureInformation->blocksInRow) + 182 (column * pixelByte * TEXTURE_BLOCK_SIZE); 183 184 /* read uint image from linear format buffer */ 185 for (s32 i = 0; i < TEXTURE_BLOCK_SIZE; i++) 186 { 187 memcpy(buf, pSrc, pixelByte * TEXTURE_BLOCK_SIZE); 188 buf += pixelByte * TEXTURE_BLOCK_SIZE; 189 pSrc += pixelByte * textureInformation->width; 190 } 191 } 192 193 return 1; 194 } 195 WriteBlock(u32 no,const u8 * pSrc,TextureInformation * textureInformation)196 static s32 WriteBlock(u32 no, const u8* pSrc, TextureInformation* textureInformation) 197 { 198 u32 row = (no / textureInformation->blocksInRow); 199 u32 column = (no % textureInformation->blocksInRow); 200 u32 pixelByte = GetPixelByte(textureInformation->format); 201 202 /* Read src uint */ 203 if (textureInformation->mode == TEXTURE_BLOCK_TO_LINE_MODE) 204 { 205 /* Get destination buffer pointer */ 206 u8* pDst; 207 208 /* Get destination pointer */ 209 if (textureInformation->yflip) 210 { 211 pDst = textureInformation->dst + 212 ((textureInformation->blocksInCol - row - 1) * TEXTURE_PIXELS_IN_BLOCK * pixelByte * 213 textureInformation->blocksInRow) + column * pixelByte * TEXTURE_BLOCK_SIZE; 214 } 215 else 216 { 217 pDst = textureInformation->dst + 218 (row * TEXTURE_PIXELS_IN_BLOCK * pixelByte * textureInformation->blocksInRow) + 219 column * pixelByte * TEXTURE_BLOCK_SIZE; 220 } 221 222 /* write uint image to linear format buffer */ 223 DeBlock(pSrc, pDst, TEXTURE_BLOCK_SIZE, textureInformation); 224 } 225 else // if (mode == L2B) 226 { 227 /* Get destination buffer pointer */ 228 u8* pDst; 229 230 if (textureInformation->yflip) 231 { 232 pDst = textureInformation->dst + 233 ((textureInformation->blocksInCol - row - 1) * textureInformation->blocksInRow + column) * 234 TEXTURE_PIXELS_IN_BLOCK * pixelByte; 235 } 236 else 237 { 238 pDst = textureInformation->dst + 239 no * TEXTURE_PIXELS_IN_BLOCK * pixelByte; 240 } 241 242 /* write uint image to block format buffer */ 243 EnBlock(pSrc, pDst, TEXTURE_BLOCK_SIZE, textureInformation); 244 } 245 246 return 1; 247 } 248 DeBlock(const u8 * pSrc,u8 * pDst,s32 blocksize,TextureInformation * textureInformation)249 static s32 DeBlock(const u8* pSrc, u8* pDst, s32 blocksize, TextureInformation* textureInformation) 250 { 251 u32 pixelByte = GetPixelByte(textureInformation->format); 252 253 if (blocksize != 1) 254 { 255 s32 pixels; 256 blocksize >>= 1; 257 pixels = blocksize * blocksize; 258 //s32 dstWidth = textureInformation->width; 259 260 if (!textureInformation->yflip) 261 { 262 DeBlock(pSrc + (pixelByte * pixels * 0), 263 pDst, blocksize, textureInformation); 264 265 DeBlock(pSrc + (pixelByte * pixels * 1), 266 pDst + (pixelByte * blocksize), 267 blocksize, textureInformation); 268 269 DeBlock(pSrc + (pixelByte * pixels * 2), 270 pDst + (pixelByte * textureInformation->width * blocksize), 271 blocksize, textureInformation); 272 273 DeBlock(pSrc + (pixelByte * pixels * 3), 274 pDst + (pixelByte * (blocksize + (textureInformation->width * blocksize))), 275 blocksize, textureInformation); 276 } 277 else 278 { 279 DeBlock(pSrc + (pixelByte * pixels * 0), 280 pDst + (pixelByte * textureInformation->width*blocksize), 281 blocksize, textureInformation); 282 283 DeBlock(pSrc + (pixelByte * pixels * 1), 284 pDst + (pixelByte * (blocksize + (textureInformation->width * blocksize))), 285 blocksize, textureInformation); 286 287 DeBlock(pSrc + (pixelByte * pixels * 2), pDst, 288 blocksize, textureInformation); 289 290 DeBlock(pSrc + (pixelByte * pixels * 3), 291 pDst+(pixelByte * blocksize), 292 blocksize, textureInformation); 293 } 294 } 295 else 296 memcpy((void*)pDst, pSrc, pixelByte); 297 298 return 1; 299 } 300 EnBlock(const u8 * pSrc,u8 * pDst,s32 blocksize,TextureInformation * textureInformation)301 static s32 EnBlock(const u8* pSrc, u8* pDst, s32 blocksize, TextureInformation* textureInformation) 302 { 303 u32 pixelByte = GetPixelByte(textureInformation->format); 304 305 if (blocksize != 1) 306 { 307 s32 pixels; 308 blocksize >>= 1; 309 pixels = blocksize * blocksize; 310 311 if (! textureInformation->yflip ) 312 { 313 EnBlock(pSrc, 314 pDst + (pixelByte * pixels * 0), 315 blocksize, textureInformation); 316 317 EnBlock(pSrc + (pixelByte * blocksize), 318 pDst + (pixelByte * pixels * 1), 319 blocksize, textureInformation); 320 321 EnBlock(pSrc + (pixelByte * blocksize * TEXTURE_BLOCK_SIZE), 322 pDst + (pixelByte * pixels * 2), 323 blocksize, textureInformation); 324 325 EnBlock(pSrc + (pixelByte * blocksize * (TEXTURE_BLOCK_SIZE + 1)), 326 pDst + (pixelByte * pixels * 3), 327 blocksize, textureInformation); 328 } 329 else 330 { 331 EnBlock(pSrc, 332 pDst + (pixelByte * pixels * 2), 333 blocksize, textureInformation); 334 335 EnBlock(pSrc + (pixelByte * blocksize), 336 pDst + (pixelByte * pixels * 3), 337 blocksize, textureInformation); 338 339 EnBlock(pSrc + (pixelByte * blocksize * TEXTURE_BLOCK_SIZE), 340 pDst + (pixelByte * pixels * 0), 341 blocksize, textureInformation); 342 343 EnBlock(pSrc + (pixelByte * blocksize * (TEXTURE_BLOCK_SIZE + 1)), 344 pDst + (pixelByte * pixels * 1), 345 blocksize, textureInformation); 346 } 347 348 } 349 else 350 { 351 memcpy((void*)pDst, pSrc, pixelByte); 352 } 353 354 return 1; 355 } 356 SwapColorComponents(TextureInformation * textureInformation)357 static s32 SwapColorComponents(TextureInformation* textureInformation) 358 { 359 if ( textureInformation->format == GL_RGBA_NATIVE_DMP ) 360 { 361 return convertFunctionArray[0](textureInformation); 362 } 363 else if ( textureInformation->format == GL_RGB_NATIVE_DMP ) 364 { 365 return convertFunctionArray[1](textureInformation); 366 } 367 else if ( textureInformation->format == GL_LUMINANCE_ALPHA_NATIVE_DMP ) 368 { 369 return convertFunctionArray[2](textureInformation); 370 } 371 else 372 { 373 return convertFunctionArray[3](textureInformation); 374 } 375 } 376 ConvertFormat8888Function(TextureInformation * textureInformation)377 static s32 ConvertFormat8888Function(TextureInformation* textureInformation) 378 { 379 u8 tmp; 380 u32 pixelByte = GetPixelByte(textureInformation->format); 381 s32 total = static_cast<s32>(textureInformation->width * textureInformation->height * pixelByte); 382 383 for (s32 i = 0; i< total; i+= pixelByte) 384 { 385 SWAP(textureInformation->src[i + 0], textureInformation->src[i + 3]); 386 SWAP(textureInformation->src[i + 1], textureInformation->src[i + 2]); 387 } 388 389 return 1; 390 } 391 ConvertFormat888Function(TextureInformation * textureInformation)392 static s32 ConvertFormat888Function(TextureInformation* textureInformation) 393 { 394 u8 tmp; 395 u32 pixelByte = GetPixelByte(textureInformation->format); 396 s32 total = static_cast<s32>(textureInformation->width * textureInformation->height * pixelByte); 397 398 for (s32 i = 0; i < total; i += pixelByte) 399 { 400 SWAP(textureInformation->src[i + 0], textureInformation->src[i + 2]); 401 } 402 403 return 1; 404 } 405 ConvertFormat88Function(TextureInformation * textureInformation)406 static s32 ConvertFormat88Function(TextureInformation* textureInformation) 407 { 408 u8 tmp; 409 u32 pixelByte = GetPixelByte(textureInformation->format); 410 s32 total = static_cast<s32>(textureInformation->width * textureInformation->height * pixelByte); 411 412 for (s32 i = 0; i < total; i += pixelByte) 413 { 414 SWAP(textureInformation->src[i+0], textureInformation->src[i+1]); 415 } 416 417 return 1; 418 } 419 ConvertFormatXXXXFunction(TextureInformation * textureInformation)420 static s32 ConvertFormatXXXXFunction(TextureInformation* textureInformation) 421 { 422 (void)textureInformation; 423 NN_TLOG_("Unsupported texture format."); 424 NN_TASSERT_(0); 425 426 return 1; 427 } 428 429 } 430