// Compiled as : // cl /DWIN32 sample.cpp yspng.cpp kernel32.lib user32.lib gdi32.lib advapi32.lib opengl32.lib glu32.lib glaux.lib // PNG ÆÄÀÏÀ» 16ºñÆ® ARGB Çü½ÄÀ¸·Î º¯È¯ÇÏ´Â ÄÚµå // ¸ðµå 0¹ø 8ºñÆ® ÆÈ·¹Æ® ¹æ½Ä // ¸ðµå 1¹ø ¾ÐÃàµÈ 8ºñÆ® ÆÈ·¹Æ® ¹æ½Ä // ¸ðµå 2¹ø 16ºñÆ® ³ë ÆÈ·¹Æ® ¹æ½Ä (*) // ¸ðµå 4¹ø 32ºñÆ® ³ë ÆÈ·¹Æ® ¹æ½Ä (*) // 0¹øÂ° ¹ÙÀÌÆ® 0x02 // 1,2 ¹øÂ° ¹ÙÀÌÆ® width // 3,4 ¹øÂ° ¹ÙÀÌÆ® height // 8¹øÂ°ºÎÅÍ À̹ÌÁö ¿¬¼Ó... #include "yspng.cpp" #include #include #include YsRawPngDecoder png; #define OSD_PIXEL_BPP 32 #define LOCAL_LITTLE_ENDIAN 0 #define LOCAL_BIG_ENDIAN 1 #define TARGET_ENDIAN LOCAL_LITTLE_ENDIAN static unsigned char pallette8[1024*100][4]; static unsigned char pallette7[1024*100][4]; static unsigned char pallette6[1024*100][4]; static unsigned char pallette[1024*100][4]; #if (OSD_PIXEL_BPP == 32) // 32ºñÆ®·Î ó¸®ÇÒ °æ¿ì void PrintNoCompress() { // return; // ±×¸² Á¤º¸ printf("\t0x%02X,\n", 4); printf("\t0x%02X, 0x%02X,\n", png.wid / 256, png.wid % 256); printf("\t0x%02X, 0x%02X,\n", png.hei / 256, png.hei % 256); printf("\t0x%02X,\n", 0); printf("\t0x%02X, 0x%02X,\n", 0, 0); // À̹ÌÁö Á¤º¸ for (int i = 0; i < png.wid * png.hei; i++) { if (i%4 == 0) printf("\n\t"); unsigned r = png.rgba[i*4]; unsigned g = png.rgba[i*4+1]; unsigned b = png.rgba[i*4+2]; unsigned a = png.rgba[i*4+3]; #if (TARGET_ENDIAN == LOCAL_LITTLE_ENDIAN) printf("0x%02X, 0x%02X, 0x%02X, 0x%02X, ", b,g,r,a); #else printf("0x%02X, 0x%02X, 0x%02X, 0x%02X, ", a,r,g,b); #endif } } void PrintCompress(int nColorCount) { // ±×¸² Á¤º¸ printf("\t0x%02X,\n", 5); printf("\t0x%02X, 0x%02X,\n", png.wid / 256, png.wid % 256); printf("\t0x%02X, 0x%02X,\n", png.hei / 256, png.hei % 256); printf("\t0x%02X,\n", 0); printf("\t0x%02X, 0x%02X,\n", nColorCount / 256, nColorCount % 256); // ÆÈ·¹Æ® // return; for (int i = 0; i < nColorCount; i++) { unsigned char r = pallette[i][0]; unsigned char g = pallette[i][1]; unsigned char b = pallette[i][2]; unsigned char a = pallette[i][3]; #if (TARGET_ENDIAN == LOCAL_LITTLE_ENDIAN) printf("\n\t0x%02X, 0x%02X, 0x%02X, 0x%02X,", b,g,r,a); #else printf("\n\t0x%02X, 0x%02X, 0x%02X, 0x%02X,", a,r,g,b); #endif } printf("\n"); // return; // 2¹ÙÀÌÆ® À̹ÌÁö if (nColorCount > 256) { for (int i = 0; i < png.wid * png.hei; i++) { if (i%8 == 0) printf("\n\t"); unsigned char r = png.rgba[i*4]; unsigned char g = png.rgba[i*4+1]; unsigned char b = png.rgba[i*4+2]; unsigned char a = png.rgba[i*4+3]; for (int j =0; j < nColorCount; j++) { if (r != pallette[j][0]) continue; if (g != pallette[j][1]) continue; if (b != pallette[j][2]) continue; if (a != pallette[j][3]) continue; #if (TARGET_ENDIAN == LOCAL_LITTLE_ENDIAN) printf("0x%02X, 0x%02X, ", j % 256, j / 256); #else printf("0x%02X, 0x%02X, ", j / 256, j % 256); #endif break; } } } else if (nColorCount > 1) // 1¹ÙÀÌÆ® À̹ÌÁö { for (int i = 0; i < png.wid * png.hei; i++) { if (i%16 == 0) printf("\n\t"); unsigned char r = png.rgba[i*4]; unsigned char g = png.rgba[i*4+1]; unsigned char b = png.rgba[i*4+2]; unsigned char a = png.rgba[i*4+3]; for (int j =0; j < nColorCount; j++) { if (r != pallette[j][0]) continue; if (g != pallette[j][1]) continue; if (b != pallette[j][2]) continue; if (a != pallette[j][3]) continue; printf("0x%02X, ", j); break; } } } } int main(int ac,char *av[]) { printf("/*\n"); png.Decode(av[1]); printf("\n*/\n"); printf("// png.wid = %d\n", png.wid); printf("// png.hei = %d\n", png.hei); // ¹è¿­ À̸§À» °áÁ¤ÇÑ´Ù. int nNameStart = 0; int i = 0; int nStrLen = (int)strlen(av[1]); for (i = 0 ; i < nStrLen; i++) { if (av[1][i] == '/') nNameStart =i+1; if (av[1][i] == '.') av[1][i] = 0; } printf("unsigned char %s[] = {\n", &av[1][nNameStart]); // alpha°¡ 0À̸é RGBµµ 0À¸·Î ¼³Á¤ÇÑ´Ù. for (int i = 0; i < png.wid * png.hei; i++) { if (png.rgba[i*4+3] == 0) // a { png.rgba[i*4+0]=0; // r png.rgba[i*4+1]=0; // g png.rgba[i*4+2]=0; // b } } int nOriginal_Size = png.wid * png.hei * 4; printf("// nOriginal_Size = %d\n", nOriginal_Size); // ÆÈ·¹Æ® »ý¼º int nColorCount8 = 0; for (int i = 0; i < png.wid * png.hei; i++) { unsigned char r = png.rgba[i*4]; unsigned char g = png.rgba[i*4+1]; unsigned char b = png.rgba[i*4+2]; unsigned char a = png.rgba[i*4+3]; bool bFind = false; for (int j = 0; j < nColorCount8; j++) { if (r != pallette8[j][0]) continue; if (g != pallette8[j][1]) continue; if (b != pallette8[j][2]) continue; if (a != pallette8[j][3]) continue; bFind = true; break; } if (bFind == false) { pallette8[nColorCount8][0] = r; pallette8[nColorCount8][1] = g; pallette8[nColorCount8][2] = b; pallette8[nColorCount8][3] = a; nColorCount8++; } } int nIndexed8_Size = nColorCount8 * 4 + (nColorCount8 > 256 ? (png.wid * png.hei*2) : (png.wid * png.hei)); printf("// nColorCount8 = %d nIndexed8_Size = %d\n", nColorCount8, nIndexed8_Size); // ÆÈ·¹Æ® »ý¼º int nColorCount7 = 0; for (int i = 0; i < nColorCount8; i++) { unsigned char r = (pallette8[i][0]/2)*2; unsigned char g = (pallette8[i][1]/2)*2; unsigned char b = (pallette8[i][2]/2)*2; unsigned char a = (pallette8[i][3]/2)*2; bool bFind = false; for (int j = 0; j < nColorCount7; j++) { if (r != pallette7[j][0]) continue; if (g != pallette7[j][1]) continue; if (b != pallette7[j][2]) continue; if (a != pallette7[j][3]) continue; bFind = true; break; } if (bFind == false) { pallette7[nColorCount7][0] = r; pallette7[nColorCount7][1] = g; pallette7[nColorCount7][2] = b; pallette7[nColorCount7][3] = a; nColorCount7++; } } int nIndexed7_Size = nColorCount7 * 4 + (nColorCount8 > 256 ? (png.wid * png.hei*2) : (png.wid * png.hei)); printf("// nColorCount7 = %d nIndexed7_Size = %d\n", nColorCount7, nIndexed7_Size); // ÆÈ·¹Æ® »ý¼º int nColorCount6 = 0; for (int i = 0; i < nColorCount7; i++) { unsigned char r = (pallette7[i][0]/4)*4; unsigned char g = (pallette7[i][1]/4)*4; unsigned char b = (pallette7[i][2]/4)*4; unsigned char a = (pallette7[i][3]/4)*4; bool bFind = false; for (int j = 0; j < nColorCount6; j++) { if (r != pallette6[j][0]) continue; if (g != pallette6[j][1]) continue; if (b != pallette6[j][2]) continue; if (a != pallette6[j][3]) continue; bFind = true; break; } if (bFind == false) { pallette6[nColorCount6][0] = r; pallette6[nColorCount6][1] = g; pallette6[nColorCount6][2] = b; pallette6[nColorCount6][3] = a; nColorCount6++; } } int nIndexed6_Size = nColorCount6 * 4 + (nColorCount8 > 256 ? (png.wid * png.hei*2) : (png.wid * png.hei)); printf("// nColorCount6 = %d nIndexed6_Size = %d\n", nColorCount6, nIndexed6_Size); //return 0; if (nOriginal_Size <= nIndexed8_Size) { printf("// PrintNoCompress\n"); PrintNoCompress(); } else { if (nColorCount8 <= 256) { printf("// PrintCompress 8\n"); memcpy(pallette, pallette8, sizeof(pallette)); PrintCompress(nColorCount8); } else { if (nColorCount7 <= 256) { // ÇÏÀ§ 1ºñÆ®¸¦ ¹ö¸°´Ù. for (int i = 0; i < png.wid * png.hei; i++) { png.rgba[i*4+0] = (png.rgba[i*4+0]/2)*2; png.rgba[i*4+1] = (png.rgba[i*4+1]/2)*2; png.rgba[i*4+2] = (png.rgba[i*4+2]/2)*2; png.rgba[i*4+3] = (png.rgba[i*4+3]/2)*2; } printf("// PrintCompress 7\n"); memcpy(pallette, pallette7, sizeof(pallette)); PrintCompress(nColorCount7); } else { if (nColorCount6 <= 256) { // ÇÏÀ§ 2ºñÆ®¸¦ ¹ö¸°´Ù. for (int i = 0; i < png.wid * png.hei; i++) { png.rgba[i*4+0] = (png.rgba[i*4+0]/4)*4; png.rgba[i*4+1] = (png.rgba[i*4+1]/4)*4; png.rgba[i*4+2] = (png.rgba[i*4+2]/4)*4; png.rgba[i*4+3] = (png.rgba[i*4+3]/4)*4; } printf("// PrintCompress 6\n"); memcpy(pallette, pallette6, sizeof(pallette)); PrintCompress(nColorCount6); } else { printf("// PrintCompress 8 16bit\n"); memcpy(pallette, pallette8, sizeof(pallette)); PrintCompress(nColorCount8); // 16ºñÆ® À̹ÌÁö·Î Ãâ·Â } } } } printf("\n};\n"); return 0; } #else // 16ºñÆ®·Î ó¸®ÇÒ °æ¿ì int main(int ac,char *av[]) { printf("/*\n"); png.Decode(av[1]); printf("\n*/\n"); printf("// png.wid = %d\n", png.wid); printf("// png.hei = %d\n", png.hei); // ¹è¿­ À̸§À» °áÁ¤ÇÑ´Ù. int nNameStart = 0; int i = 0; int nStrLen = (int)strlen(av[1]); for (i = 0 ; i < nStrLen; i++) { if (av[1][i] == '/') nNameStart =i+1; if (av[1][i] == '.') av[1][i] = 0; } printf("unsigned char %s[] = {\n", &av[1][nNameStart]); // alpha°¡ 0À̸é RGBµµ 0À¸·Î ¼³Á¤ÇÑ´Ù. for (int i = 0; i < png.wid * png.hei; i++) { if (png.rgba[i*4+3] == 0) // a { png.rgba[i*4+0]=0; // r png.rgba[i*4+1]=0; // g png.rgba[i*4+0]=0; // b } } // 16À¸·Î ³ª´«´Ù. ¾Æ·¡ 4ºñÆ®´Â Àǹ̰¡ ¾ø´Ù for (int i = 0; i < png.wid * png.hei; i++) { png.rgba[i*4+0]/=16; png.rgba[i*4+1]/=16; png.rgba[i*4+2]/=16; png.rgba[i*4+3]/=16; } // ÆÈ·¹Æ® °¹¼ö¸¦ ±¸ÇÑ´Ù. int nColorCount = 0; for (int i = 0; i < png.wid * png.hei; i++) { char r = png.rgba[i*4]; char g = png.rgba[i*4+1]; char b = png.rgba[i*4+2]; char a = png.rgba[i*4+3]; bool bFind = false; for (int j =0; j < i; j++) { char r2 = png.rgba[j*4]; char g2 = png.rgba[j*4+1]; char b2 = png.rgba[j*4+2]; char a2 = png.rgba[j*4+3]; if (r == r2 && g == g2 && b == b2 && a == a2) { bFind = true; break; } } if (bFind == false) nColorCount++; } // Original Size int nOriginal_Size = png.wid * png.hei * 2; int nIndexed_Size = 2 + nColorCount * 2 + (png.wid * png.hei); printf("// Original Size = %d\n", nOriginal_Size); printf("// Indexed Size = %d\n", nIndexed_Size); if (nIndexed_Size < nOriginal_Size && nColorCount <=16) { // ÆÈ·¹Æ® ¹è¿­¿¡ Áý¾î³Ö´Â´Ù char *pallette = (char*)calloc(nColorCount,4); int nPos = 0; for (int i = 0; i < png.wid * png.hei; i++) { char r = png.rgba[i*4]; char g = png.rgba[i*4+1]; char b = png.rgba[i*4+2]; char a = png.rgba[i*4+3]; bool bFind = false; for (int j =0; j < i; j++) { char r2 = png.rgba[j*4]; char g2 = png.rgba[j*4+1]; char b2 = png.rgba[j*4+2]; char a2 = png.rgba[j*4+3]; if (r == r2 && g == g2 && b == b2 && a == a2) { bFind = true; break; } } if (bFind == false) { pallette[nPos*4+0] = r; pallette[nPos*4+1] = g; pallette[nPos*4+2] = b; pallette[nPos*4+3] = a; nPos++; } } printf("\t0x%02X, \n", 6); printf("\t0x%02X, 0x%02X, \n", png.wid / 256, png.wid % 256); printf("\t0x%02X, 0x%02X, \n", png.hei / 256, png.hei % 256); printf("\t0x%02X, \n", nColorCount-1); for (int i = 0; i < nColorCount; i++) { char r = pallette[i*4+0]; char g = pallette[i*4+1]; char b = pallette[i*4+2]; char a = pallette[i*4+3]; #if (TARGET_ENDIAN == LOCAL_LITTLE_ENDIAN) printf("\n\t0x%01X%01X, 0x%01X%01X,", g,b,a,r); #else printf("\n\t0x%01X%01X, 0x%01X%01X,", a,r,g,b); #endif } printf("\n"); int data[2] = {0,0}; for (int i = 0; i < png.wid * png.hei; i++) { int value = 0; if (i%16 == 0) printf("\n\t"); char r = png.rgba[i*4]; char g = png.rgba[i*4+1]; char b = png.rgba[i*4+2]; char a = png.rgba[i*4+3]; for (int j =0; j < nColorCount; j++) { char r2 = pallette[j*4+0]; char g2 = pallette[j*4+1]; char b2 = pallette[j*4+2]; char a2 = pallette[j*4+3]; if (r == r2 && g == g2 && b == b2 && a == a2) { // printf("0x%02X, ", j); value = j; break; } } if (i%2 == 0) { data[0] = value; data[1] = -1; } else { data[1] = value; printf("0x%02X, ", data[0]*16 + data[1]); } } if (data[1] == -1) printf("0x%02X, ", data[0]*16); free(pallette); } else if (nIndexed_Size < nOriginal_Size && nColorCount <=256) { // ÆÈ·¹Æ® ¹è¿­¿¡ Áý¾î³Ö´Â´Ù char *pallette = (char*)calloc(nColorCount,4); int nPos = 0; for (int i = 0; i < png.wid * png.hei; i++) { char r = png.rgba[i*4]; char g = png.rgba[i*4+1]; char b = png.rgba[i*4+2]; char a = png.rgba[i*4+3]; bool bFind = false; for (int j =0; j < i; j++) { char r2 = png.rgba[j*4]; char g2 = png.rgba[j*4+1]; char b2 = png.rgba[j*4+2]; char a2 = png.rgba[j*4+3]; if (r == r2 && g == g2 && b == b2 && a == a2) { bFind = true; break; } } if (bFind == false) { pallette[nPos*4+0] = r; pallette[nPos*4+1] = g; pallette[nPos*4+2] = b; pallette[nPos*4+3] = a; nPos++; } } printf("\t0x%02X, \n", 6); printf("\t0x%02X, 0x%02X, \n", png.wid / 256, png.wid % 256); printf("\t0x%02X, 0x%02X, \n", png.hei / 256, png.hei % 256); printf("\t0x%02X, \n", nColorCount-1); for (int i = 0; i < nColorCount; i++) { char r = pallette[i*4+0]; char g = pallette[i*4+1]; char b = pallette[i*4+2]; char a = pallette[i*4+3]; #if (TARGET_ENDIAN == LOCAL_LITTLE_ENDIAN) printf("\n\t0x%01X%01X, 0x%01X%01X,", g,b,a,r); #else printf("\n\t0x%01X%01X, 0x%01X%01X,", a,r,g,b); #endif } printf("\n"); for (int i = 0; i < png.wid * png.hei; i++) { if (i%16 == 0) printf("\n\t"); char r = png.rgba[i*4]; char g = png.rgba[i*4+1]; char b = png.rgba[i*4+2]; char a = png.rgba[i*4+3]; for (int j =0; j < nColorCount; j++) { char r2 = pallette[j*4+0]; char g2 = pallette[j*4+1]; char b2 = pallette[j*4+2]; char a2 = pallette[j*4+3]; if (r == r2 && g == g2 && b == b2 && a == a2) { printf("0x%02X, ", j); break; } } } free(pallette); } else { printf("\t0x%02X, \n", 2); printf("\t0x%02X, 0x%02X, \n", png.wid / 256, png.wid % 256); printf("\t0x%02X, 0x%02X, \n", png.hei / 256, png.hei % 256); printf("\t0x%02X, \n", 0); for (int i = 0; i < png.wid * png.hei; i++) { if (i%4 == 0) printf("\n\t"); unsigned r = png.rgba[i*4]; unsigned g = png.rgba[i*4+1]; unsigned b = png.rgba[i*4+2]; unsigned a = png.rgba[i*4+3]; #if (TARGET_ENDIAN == LOCAL_LITTLE_ENDIAN) //printf("\n\t0x%01X%01X, 0x%01X%01X,", b,g,r,a); printf("\n\t0x%01X%01X, 0x%01X%01X,", g,b,a,r); #else printf("\n\t0x%01X%01X, 0x%01X%01X,", a,r,g,b); #endif } } printf("\n};\n"); return 0; } #endif