void yuv2rgb24(int *blk,unsigned char *image) { int x,y; int *Yblk = blk+DCTSIZE2*2; int Cb,Cr,R,G,B; int *Cbblk = blk; int *Crblk = blk+DCTSIZE2; if (!(Config.Mdec&0x1)) for (y=0;y<16;y+=2,Crblk+=4,Cbblk+=4,Yblk+=8,image+=24*3) { if (y==8) Yblk+=DCTSIZE2; for (x=0;x<4;x++,image+=6,Crblk++,Cbblk++,Yblk+=2) { Cr = *Crblk; Cb = *Cbblk; R = MULR(Cr); G = MULG(Cb) + MULG2(Cr); B = MULB(Cb); RGB24(0, Yblk[0]); RGB24(1*3, Yblk[1]); RGB24(16*3, Yblk[8]); RGB24(17*3, Yblk[9]); Cr = *(Crblk+4); Cb = *(Cbblk+4); R = MULR(Cr); G = MULG(Cb) + MULG2(Cr); B = MULB(Cb); RGB24(8*3, Yblk[DCTSIZE2+0]); RGB24(9*3, Yblk[DCTSIZE2+1]); RGB24(24*3, Yblk[DCTSIZE2+8]); RGB24(25*3, Yblk[DCTSIZE2+9]); } } else for (y=0;y<16;y+=2,Yblk+=8,image+=24*3) { if (y==8) Yblk+=DCTSIZE2; for (x=0;x<4;x++,image+=6,Yblk+=2) { RGB24BW(0, Yblk[0]); RGB24BW(1*3, Yblk[1]); RGB24BW(16*3, Yblk[8]); RGB24BW(17*3, Yblk[9]); RGB24BW(8*3, Yblk[DCTSIZE2+0]); RGB24BW(9*3, Yblk[DCTSIZE2+1]); RGB24BW(24*3, Yblk[DCTSIZE2+8]); RGB24BW(25*3, Yblk[DCTSIZE2+9]); } } }
void ConvertToHeader(const char* inFile, const char* outFile, i32 posX, i32 posY, i32 sizeX, i32 sizeY, i32 numX, i32 numY, i32 colorNum, u32 transColor, const char* name, Compressor comp, LangageInterface* lang) { FIBITMAP *dib, *dib32; i32 i, j, nx, ny, bit, minX, maxX, minY, maxY, width, height, totalBytes = 0; std::string outData; RGB24 c24; GRB8 c8; u8 byte = 0; dib = LoadImage(inFile); // open and load the file using the default load option if(dib != NULL) { // Get 32 bits version dib32 = FreeImage_ConvertTo32Bits(dib); FreeImage_Unload(dib); // free the original dib i32 imageX = FreeImage_GetWidth(dib32); i32 imageY = FreeImage_GetHeight(dib32); i32 scanWidth = FreeImage_GetPitch(dib32); i32 bpp = FreeImage_GetBPP(dib32); BYTE *bits = new BYTE[scanWidth * imageY]; FreeImage_ConvertToRawBits(bits, dib32, scanWidth, 32, FI_RGBA_RED_MASK, FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK, TRUE); FreeImage_Unload(dib32); // Build header file outData += lang->Header(VERSION, name); for(ny = 0; ny < numY; ny++) { for(nx = 0; nx < numX; nx++) { // Compute bound for crop compression if(comp != COMPRESS_None) { minX = sizeX; maxX = 0; minY = sizeY; maxY = 0; for(j = 0; j < sizeY; j++) { for(i = 0; i < sizeX; i++) { i32 pixel = posX + i + (nx * sizeX) + ((posY + j + (ny * sizeY)) * imageX); u32 argb = ((u32*)bits)[pixel]; if((argb & 0xFFFFFF) != transColor) { if(i < minX) minX = i; if(i > maxX) maxX = i; if(j < minY) minY = j; if(j > maxY) maxY = j; } } } width = maxX > minX ? 1 + maxX - minX : 0; height = maxY > minY ? 1 + maxY - minY : 0; } // Print sprite header outData += lang->SpriteBegin(nx + ny * numX); if(comp == COMPRESS_Crop256) { outData += lang->Line4Bytes(u8(minX), u8(minY), u8(width), u8(height), "minX minY sizeX sizeY"); totalBytes += 4; } else if(comp == COMPRESS_Crop32) { if(width == 0 || height == 0) { outData += lang->Line1Byte(0x80, "no data"); totalBytes += 1; } else { minX >>= 3; maxX >>= 3; width = maxX - minX; minY &= 0x1F; // Clamp to 5bits (0-31) height--; height &= 0x1F; if(minX == 0 && minY == 0) { outData += lang->Line1Byte(u8(0x80 + (width << 5) + height), "sizeX(2b)|sizeY(5b)"); totalBytes += 1; } else { outData += lang->Line2Bytes(u8((minX << 5) + minY), u8(0x80 + (width << 5) + height), "minX(2b)|minY(5b) sizeX(2b)|sizeY(5b)"); totalBytes += 2; } minX *= 8; maxX = (maxX * 8) + 7; width = (width + 1) * 8; } } else if(comp == COMPRESS_Crop16) { minX &= 0x0F; // Clamp to 4bits (0-15) width &= 0x0F; minY &= 0x0F; height &= 0x0F; outData += lang->Line2Bytes(u8((minX << 4) + minY), u8(((width) << 4) + (height)), "minX|minY sizeX|sizeY"); totalBytes += 2; } else if(comp == COMPRESS_CropLine16) { outData += lang->Line1Byte(u8((minY << 4) + (height)), "minY|sizeY"); totalBytes += 1; } // Print sprite content for(j = 0; j < sizeY; j++) { if((comp == COMPRESS_None) || ((j >= minY) && (j <= maxY))) { outData += lang->LineBegin(); if(comp == COMPRESS_CropLine16) // for line-crop, we need to recompute minX&maxX for each line { minX = sizeX; maxX = 0; for(i = 0; i < sizeX; i++) { i32 pixel = posX + i + (nx * sizeX) + ((posY + j + (ny * sizeY)) * imageX); u32 argb = ((u32*)bits)[pixel]; if((argb & 0xFFFFFF) != transColor) { if(i < minX) minX = i; if(i > maxX) maxX = i; } } outData += lang->Line1Byte(u8((minX << 4) + (1 + maxX - minX)), "minX|sizeX"); } for(i = 0; i < sizeX; i++) { if((comp == COMPRESS_None) || ((i >= minX) && (i <= maxX))) { i32 pixel = posX + i + (nx * sizeX) + ((posY + j + (ny * sizeY)) * imageX); u32 argb = ((u32*)bits)[pixel]; if(colorNum == 256) { // convert to 8 bits GRB if((argb & 0xFFFFFF) == transColor) { c8 = 0; } else { c24 = RGB24(argb); c8 = GRB8(c24); if(c8 == 0) { if(c24.G > c24.R) c8 = 0x20; else c8 = 0x04; } } outData += lang->Data8Bits((u8)c8); totalBytes++; } else if(colorNum == 16) { } else if(colorNum == 2) { bit = pixel & 0x7; if((argb & 0xFFFFFF) != transColor) byte |= 1 << (7 - bit); if((pixel & 0x7) == 0x7) { outData += lang->Data1Bit(byte); totalBytes++; byte = 0; } } } } outData += lang->LineEnd(); } } } }