1 // Copyright 2001-2018 Crytek GmbH / Crytek Group. All rights reserved.
4 #include <assert.h> // assert()
6 #include "../ImageObject.h" // ImageObject, EPixelFormat
8 #include "IRCLog.h" // RCLogError()
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)
23 pixels
[0] = tmp
[pSwizzleIndices
[0]];
24 pixels
[1] = tmp
[pSwizzleIndices
[1]];
25 pixels
[2] = tmp
[pSwizzleIndices
[2]];
29 else if (channelCount
== 4)
37 pixels
[0] = tmp
[pSwizzleIndices
[0]];
38 pixels
[1] = tmp
[pSwizzleIndices
[1]];
39 pixels
[2] = tmp
[pSwizzleIndices
[2]];
40 pixels
[3] = tmp
[pSwizzleIndices
[3]];
51 bool ImageObject::Swizzle(const char* swizzle
)
53 if (swizzle
== 0 || swizzle
[0] == 0)
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)
64 RCLogError("%s: unsupported source format. Contact an RC programmer.", __FUNCTION__
);
68 if (strlen(swizzle
) < pFormatInfo
->nChannels
)
71 RCLogError("%s: bad number of channels in swizzle parameter: %s. Contact an RC programmer.", __FUNCTION__
, swizzle
);
75 if (stricmp(swizzle
, "rgba") == 0 || stricmp(swizzle
, "rgb") == 0)
77 // No changes requested
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
)
91 swizzleIndices
[i
] = bBgrOrder
? 2 : 0;
95 swizzleIndices
[i
] = 1;
99 swizzleIndices
[i
] = bBgrOrder
? 0 : 2;
103 swizzleIndices
[i
] = 3;
106 swizzleIndices
[i
] = 4;
109 swizzleIndices
[i
] = 5;
116 std::swap(swizzleIndices
[0], swizzleIndices
[2]);
120 for (uint32 mip
= 0; mip
< GetMipCount(); ++mip
)
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
);
145 RCLogError("%s: unsupported sample type. Contact an RC programmer.", __FUNCTION__
);