Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include "pvrtc.h" // libPVRTC
- // Конвертируем изображение в формат PVRTC. Лучшее качество при quality = 4.
- Image ImageConvertArgbToPvrtc(const Image& img, unsigned int format, int quality)
- {
- if ( !isPvrtcFormat(format) ) {
- dbgfail("Not a PVRTC format: "+ utils::lexical_cast(format));
- return Image();
- }
- // Конвертирование работает только из формата ARGB.
- if ( img.GetPixelType() != PIXEL_TYPE_ARGB ) {
- dbgfail("Not an ARGB image: "+ PixelTypeToString(img.GetPixelType()));
- return Image();
- }
- // Изображение должно быть квадратное со сторонами, равными степени двойки.
- if (img.w != Math::Pow2Ceil(img.w) || img.h != Math::Pow2Ceil(img.h) || img.w != img.h) {
- dbgfail("Image sizes should be Pow2 and equal. Now w = "+ utils::lexical_cast(img.w) + ", h = " + utils::lexical_cast(img.h));
- return Image();
- }
- int bUse2bitFormat = (format == FORMAT_PVRTC2_RGB || format == FORMAT_PVRTC2_RGBA) ? 1 : 0;
- int bMipMap = 0;
- int w = img.w;
- int h = img.h;
- Assert(w == Math::Pow2Ceil(w) && h == Math::Pow2Ceil(h));
- int bin_sz = pvrtc_size(w, h, bMipMap, bUse2bitFormat);
- ImageData::Ref dst = ImageData::CreateRaw(w, h, bin_sz, format);
- void * inputARGBData = img.Data();
- void * outputCompressedData = dst->Data();
- int bAlphaOn = (format == FORMAT_PVRTC2_RGBA || format == FORMAT_PVRTC4_RGBA) ? 1 : 0;
- pvrtc_compress(inputARGBData, outputCompressedData, w, h, bMipMap, bAlphaOn, bUse2bitFormat, quality);
- return Image(dst);
- }
- // Ну и вот так я записываю PVRTC в файл (возможно, не самый правильный способ).
- void ImageData::WritePVRTC(const std::string& filename) const
- {
- if (pixelType != PIXEL_TYPE_COMPRESSED) {
- dbgfail("WritePVRTC: not a compressed data. pixelType = " + PixelTypeToString(pixelType));
- return;
- }
- struct {
- uint32_t headerLength;
- uint32_t height;
- uint32_t width;
- uint32_t mipmaps;
- uint32_t flags;
- uint32_t dataLength;
- uint32_t bpp;
- uint32_t bitmaskR;
- uint32_t bitmaskG;
- uint32_t bitmaskB;
- uint32_t bitmaskA;
- uint32_t PVR;
- uint32_t surfaces;
- } header;
- header.headerLength = sizeof(header);
- header.height = h;
- header.width = w;
- header.mipmaps = 0;
- header.flags = 0;
- header.dataLength = dataSize;
- header.bpp = 4;
- header.bitmaskR = 1;
- header.bitmaskG = 1;
- header.bitmaskB = 1;
- header.bitmaskA = 1;
- header.PVR = 0x21525650;
- header.surfaces = 1;
- switch (compressedFormat) {
- case FORMAT_PVRTC2_RGB:
- header.flags = 0x18; // OGL_PVRTC2
- header.bitmaskA = 0;
- break;
- case FORMAT_PVRTC2_RGBA:
- header.flags = 0x18; // OGL_PVRTC2
- header.bitmaskA = 1;
- break;
- case FORMAT_PVRTC4_RGB:
- header.flags = 0x19; // OGL_PVRTC4
- header.bitmaskA = 0;
- break;
- case FORMAT_PVRTC4_RGBA:
- header.flags = 0x19; // OGL_PVRTC4
- header.bitmaskA = 1;
- break;
- default:
- dbgfail("Unknown compressed format "+ utils::lexical_cast(compressedFormat));
- return;
- }
- header.flags |= 0x10000; // For PVRTexTool to know that image is flipped.
- File::c_file f;
- f.open_to_write(filename);
- if (!f.is_open()) { dbgfail("LoadPVRTC: Can't open file '"+ filename +"'."); }
- f.write(&header, sizeof(header));
- f.write(data, dataSize);
- f.close();
- }
- // Ну и немного определений, которые выше использовались.
- #define FORMAT_PVRTC4_RGB 0x8c00
- #define FORMAT_PVRTC2_RGB 0x8C01
- #define FORMAT_PVRTC4_RGBA 0x8C02
- #define FORMAT_PVRTC2_RGBA 0x8C03
- inline bool isPvrtcFormat(unsigned int format)
- {
- return ( format == FORMAT_PVRTC4_RGB
- || format == FORMAT_PVRTC2_RGB
- || format == FORMAT_PVRTC4_RGBA
- || format == FORMAT_PVRTC2_RGBA
- );
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement