!I (1670414, 1670415, 1670416, 1670424, 1670431):
[CRYENGINE.git] / Code / Tools / RC / ResourceCompilerImage / Converters / SwizzleAndCopy.cpp
blob6c7576029303ed490463e5fd9755c4545870b651
1 // Copyright 2001-2018 Crytek GmbH / Crytek Group. All rights reserved.
3 #include "stdafx.h"
4 #include <assert.h> // assert()
6 #include "../ImageObject.h" // ImageObject, EPixelFormat
8 #include "IRCLog.h" // RCLogError()
11 template <class T>
12 static void SwizzlePixels(T* pixels, const int channelCount, uint32 pixelCount, const T zero, const T one, const int* const pSwizzleIndices)
14 T tmp[6] = { zero, zero, zero, one, zero, one };
16 if (channelCount == 3)
18 while (pixelCount--)
20 tmp[0] = pixels[0];
21 tmp[1] = pixels[1];
22 tmp[2] = pixels[2];
23 pixels[0] = tmp[pSwizzleIndices[0]];
24 pixels[1] = tmp[pSwizzleIndices[1]];
25 pixels[2] = tmp[pSwizzleIndices[2]];
26 pixels += 3;
29 else if (channelCount == 4)
31 while (pixelCount--)
33 tmp[0] = pixels[0];
34 tmp[1] = pixels[1];
35 tmp[2] = pixels[2];
36 tmp[3] = pixels[3];
37 pixels[0] = tmp[pSwizzleIndices[0]];
38 pixels[1] = tmp[pSwizzleIndices[1]];
39 pixels[2] = tmp[pSwizzleIndices[2]];
40 pixels[3] = tmp[pSwizzleIndices[3]];
41 pixels += 4;
44 else
46 assert(0);
51 bool ImageObject::Swizzle(const char* swizzle)
53 if (swizzle == 0 || swizzle[0] == 0)
55 return true;
58 const EPixelFormat eFormat = GetPixelFormat();
59 const PixelFormatInfo* const pFormatInfo = CPixelFormats::GetPixelFormatInfo(eFormat);
61 if (!pFormatInfo || pFormatInfo->eSampleType == eSampleType_Compressed || pFormatInfo->nChannels < 3 || pFormatInfo->nChannels > 4)
63 assert(0);
64 RCLogError("%s: unsupported source format. Contact an RC programmer.", __FUNCTION__);
65 return false;
68 if (strlen(swizzle) < pFormatInfo->nChannels)
70 assert(0);
71 RCLogError("%s: bad number of channels in swizzle parameter: %s. Contact an RC programmer.", __FUNCTION__, swizzle);
72 return false;
75 if (stricmp(swizzle, "rgba") == 0 || stricmp(swizzle, "rgb") == 0)
77 // No changes requested
78 return true;
81 int swizzleIndices[4];
83 const bool bBgrOrder = eFormat == ePixelFormat_A8R8G8B8 || eFormat == ePixelFormat_X8R8G8B8 || eFormat == ePixelFormat_R8G8B8;
85 for (int i = 0; i < pFormatInfo->nChannels; ++i)
87 switch (swizzle[i])
89 case 'r':
90 case 'R':
91 swizzleIndices[i] = bBgrOrder ? 2 : 0;
92 break;
93 case 'g':
94 case 'G':
95 swizzleIndices[i] = 1;
96 break;
97 case 'b':
98 case 'B':
99 swizzleIndices[i] = bBgrOrder ? 0 : 2;
100 break;
101 case 'a':
102 case 'A':
103 swizzleIndices[i] = 3;
104 break;
105 case '0':
106 swizzleIndices[i] = 4;
107 break;
108 case '1':
109 swizzleIndices[i] = 5;
110 break;
114 if (bBgrOrder)
116 std::swap(swizzleIndices[0], swizzleIndices[2]);
120 for (uint32 mip = 0; mip < GetMipCount(); ++mip)
122 char *pMem;
123 uint32 dwPitch;
124 GetImagePointer(mip, pMem, dwPitch);
126 if (pFormatInfo->eSampleType == eSampleType_Uint8)
128 ::SwizzlePixels<uint8>((uint8*)pMem, pFormatInfo->nChannels, GetPixelCount(mip), 0, 255, swizzleIndices);
130 else if (pFormatInfo->eSampleType == eSampleType_Uint16)
132 ::SwizzlePixels<uint16>((uint16*)pMem, pFormatInfo->nChannels, GetPixelCount(mip), 0, 0xffff, swizzleIndices);
134 else if (pFormatInfo->eSampleType == eSampleType_Half)
136 ::SwizzlePixels<SHalf>(reinterpret_cast<SHalf*>(pMem), pFormatInfo->nChannels, GetPixelCount(mip), SHalf(0.0f), SHalf(1.0f), swizzleIndices);
138 else if (pFormatInfo->eSampleType == eSampleType_Float)
140 ::SwizzlePixels<float>((float*)(void*)pMem, pFormatInfo->nChannels, GetPixelCount(mip), 0.0f, 1.0f, swizzleIndices);
142 else
144 assert(0);
145 RCLogError("%s: unsupported sample type. Contact an RC programmer.", __FUNCTION__);
146 return false;
150 return true;