ipf codec mostly works except no dithering

This commit is contained in:
minjaesong
2022-05-01 18:08:21 +09:00
parent 37d6f76a5f
commit 14b624fb08
2 changed files with 57 additions and 36 deletions

View File

@@ -139,42 +139,50 @@ if (!magicMatching) {
let imgw = readShort()
let imgh = readShort()
let hasAlpha = (readShort() != 0)
sys.free(readBytes(12)) // skip 10 bytes
sys.free(readBytes(10)) // skip 10 bytes
// TODO: gzip
function clampRGB(f) {
return (f > 1.0) ? 1.0 : (f < 0.0) ? 0.0 : f
}
function ycocgToRGB(cocg, ys, as) { // ys: 4 Y-values
// return [R1|G1, B1|A1, R2|G2, B2|A2, R3|G3, B3|A3, R4|G4, B4|A4]
let co = 0.0//((cocg & 15) - 7.5) / 7.5
let cg = 0.0//((cocg >> 4) & 15 - 7.5) / 7.5
// cocg = 0x7777
// ys = 0x0000
let co = ((cocg & 15) - 7) / 8
let cg = (((cocg >>> 4) & 15) - 7) / 8
let y1 = (ys & 15) / 15.0
let a1 = as & 15
let tmp = y1 - cg / 2
let g1 = cg + tmp
let b1 = tmp - co / 2
let r1 = b1 + co
let tmp = y1 - cg / 2.0
let g1 = clampRGB(cg + tmp)
let b1 = clampRGB(tmp - co / 2.0)
let r1 = clampRGB(b1 + co)
let y2 = ((ys >> 4) & 15) / 15.0
let a2 = (as >> 4) & 15
tmp = y2 - cg / 2
let g2 = cg + tmp
let b2 = tmp - co / 2
let r2 = b2 + co
let y2 = ((ys >>> 4) & 15) / 15.0
let a2 = (as >>> 4) & 15
tmp = y2 - cg / 2.0
let g2 = clampRGB(cg + tmp)
let b2 = clampRGB(tmp - co / 2.0)
let r2 = clampRGB(b2 + co)
let y3 = ((ys >> 8) & 15) / 15.0
let a3 = (as >> 8) & 15
tmp = y3 - cg / 2
let g3 = cg + tmp
let b3 = tmp - co / 2
let r3 = b3 + co
let y3 = ((ys >>> 8) & 15) / 15.0
let a3 = (as >>> 8) & 15
tmp = y3 - cg / 2.0
let g3 = clampRGB(cg + tmp)
let b3 = clampRGB(tmp - co / 2.0)
let r3 = clampRGB(b3 + co)
let y4 = ((ys >> 12) & 15) / 15.0
let a4 = (as >> 12) & 15
tmp = y4 - cg / 2
let g4 = cg + tmp
let b4 = tmp - co / 2
let r4 = b4 + co
let y4 = ((ys >>> 12) & 15) / 15.0
let a4 = (as >>> 12) & 15
tmp = y4 - cg / 2.0
let g4 = clampRGB(cg + tmp)
let b4 = clampRGB(tmp - co / 2.0)
let r4 = clampRGB(b4 + co)
return [
(Math.round(r1 * 15) << 4) | Math.round(g1 * 15),
@@ -204,6 +212,17 @@ for (let blockX = 0; blockX < Math.ceil(imgw / 4.0); blockX++) {
let cocg4 = readByte()
let y4 = readShort()
if (blockX == 0 && blockY == 0) {
serial.println(`cocg: ${(cocg1 & 15).toString(16)} ${((cocg1 >>> 4) & 15).toString(16)}`)
serial.println(`y: ${y1.toString(16)}`)
serial.println(`cocg: ${cocg2.toString(16)}`)
serial.println(`y: ${y2.toString(16)}`)
serial.println(`cocg: ${cocg3.toString(16)}`)
serial.println(`y: ${y3.toString(16)}`)
serial.println(`cocg: ${cocg4.toString(16)}`)
serial.println(`y: ${y4.toString(16)}`)
}
let a1 = 65535; let a2 = 65535; let a3 = 65535; let a4 = 65535
if (hasAlpha) {

View File

@@ -105,7 +105,8 @@ let writeCount = 0
let writeBuf = sys.malloc(blockSize * ((hasAlpha) ? 20 : 12))
function chromaToFourBits(f) {
return Math.round((f * 7.5) + 7.5)
let r = Math.round(f * 8) + 7
return (r < 0) ? 0 : (r > 15) ? 15 : r
}
for (let blockY = 0; blockY < Math.ceil(imgh / 4.0); blockY++) {
@@ -124,6 +125,7 @@ for (let blockX = 0; blockX < Math.ceil(imgw / 4.0); blockX++) {
let ox = blockX * 4 + px
let oy = blockY * 4 + py
let offset = channels * (oy * imgw + ox)
let r = sys.peek(imageData + offset) / 255.0
let g = sys.peek(imageData + offset+1) / 255.0
let b = sys.peek(imageData + offset+2) / 255.0
@@ -142,14 +144,14 @@ for (let blockX = 0; blockX < Math.ceil(imgw / 4.0); blockX++) {
}}
// subsample by averaging
let cos1 = chromaToFourBits((cos[0]+cos[1]+cos[4]+cos[5]) / 8.0)
let cos2 = chromaToFourBits((cos[2]+cos[3]+cos[6]+cos[7]) / 8.0)
let cos3 = chromaToFourBits((cos[8]+cos[9]+cos[12]+cos[13]) / 8.0)
let cos4 = chromaToFourBits((cos[10]+cos[11]+cos[14]+cos[15]) / 8.0)
let cgs1 = chromaToFourBits((cgs[0]+cgs[1]+cgs[4]+cgs[5]) / 8.0)
let cgs2 = chromaToFourBits((cgs[2]+cgs[3]+cgs[6]+cgs[7]) / 8.0)
let cgs3 = chromaToFourBits((cgs[8]+cgs[9]+cgs[12]+cgs[13]) / 8.0)
let cgs4 = chromaToFourBits((cgs[10]+cgs[11]+cgs[14]+cgs[15]) / 8.0)
let cos1 = chromaToFourBits((cos[0]+cos[1]+cos[4]+cos[5]) / 4.0)
let cos2 = chromaToFourBits((cos[2]+cos[3]+cos[6]+cos[7]) / 4.0)
let cos3 = chromaToFourBits((cos[8]+cos[9]+cos[12]+cos[13]) / 4.0)
let cos4 = chromaToFourBits((cos[10]+cos[11]+cos[14]+cos[15]) / 4.0)
let cgs1 = chromaToFourBits((cgs[0]+cgs[1]+cgs[4]+cgs[5]) / 4.0)
let cgs2 = chromaToFourBits((cgs[2]+cgs[3]+cgs[6]+cgs[7]) / 4.0)
let cgs3 = chromaToFourBits((cgs[8]+cgs[9]+cgs[12]+cgs[13]) / 4.0)
let cgs4 = chromaToFourBits((cgs[10]+cgs[11]+cgs[14]+cgs[15]) / 4.0)
// append encoded blocks to the file
let outBlock = writeBuf + writeCount
@@ -185,8 +187,8 @@ for (let blockX = 0; blockX < Math.ceil(imgw / 4.0); blockX++) {
// write header to the output file
let headerBytes = [
0x1F, 0x54, 0x53, 0x56, 0x4D, 0x69, 0x50, 0x46, // magic
imgw & 255, (imgw >> 8) & 255, // width
imgh & 255, (imgh >> 8) & 255, // height
imgw & 255, (imgw >>> 8) & 255, // width
imgh & 255, (imgh >>> 8) & 255, // height
((hasAlpha) ? 1 : 0), 0x00, // has alpha
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 // reserved
]