PNGのパレット変換
PNGのパレット変換は、PLTEチャンクが固定された位置にないので検索しなければならないのと、CRCの計算をしなくてはならないので、ちょっと複雑になります。
private int[] crc_table = null; /** * @brief PNG 画像のパレット変更を行います。 * * @param buf PNG 画像のデータが入ったバッファ * @param pal パレット画像のデータが入ったバッファ * (PNG のパレットデータの形式に準ずる) * * @return @a buf をコピーしてパレットデータを書き換えたバッファを返します。 */ private byte[] changePalette(byte[] buf, byte[] pal) { byte[] buf2; buf2 = new byte[buf.length]; System.arraycopy(buf, 0, buf2, 0, buf.length); int length; int signature; int seek; // PNG signature + IHDR Chunk seek = 8 + 25; while (true) { length = ((buf[seek + 0] & 0xff) << 24) | ((buf[seek + 1] & 0xff) << 16) | ((buf[seek + 2] & 0xff) << 8) | ((buf[seek + 3] & 0xff) << 0); seek += 4; signature = ((buf[seek + 0] & 0xff) << 24) | ((buf[seek + 1] & 0xff) << 16) | ((buf[seek + 2] & 0xff) << 8) | ((buf[seek + 3] & 0xff) << 0); seek += 4; if (signature == 0x504C5445) // PLTE { int size, crc; size = (length < pal.length) ? length : pal.length; // copy palette System.arraycopy(pal, 0, buf2, seek, size); if (crc_table == null) { // make CRC table int c,n,k; crc_table = new crc_table[256]; for (n = 0; n < 256; n++) { c = n; for (k = 0; k < 8; k++) { if ((c & 1) != 0) c = (c >>> 1) ^ 0xedb88320; else c = (c >>> 1); } crc_table[n] = c; } } // calculate CRC crc = 0xffffffff; int last = seek + size; seek -= 4; for (; seek < last; seek++) { crc = crc_table[(crc ^ (int)buf2[seek]) & 0xff] ^ (crc >>> 8); } crc ^= 0xffffffff; // write CRC buf2[seek++] = (crc >>> 24) & 0xff; buf2[seek++] = (crc >>> 16) & 0xff; buf2[seek++] = (crc >>> 8) & 0xff; buf2[seek++] = (crc >>> 0) & 0xff; break; } seek += length + 4; } return buf2; }
めんどい(;´Д`)