// This file is distributed under a BSD license. See LICENSE.txt for details. // FRIED // encoding functions. #include "_types.hpp" #include "fried.hpp" #include "fried_internal.hpp" namespace FRIED { static void read_bitmap_row(EncodeContext &ctx,sInt row,sInt *srp) { if(row < 0) row = 0; else if(row >= ctx.FH.YRes) row = ctx.FH.YRes - 1; sInt cols = ctx.FH.XRes; sInt colsPad = ctx.XResPadded; const sU8 *src = ctx.Image; if(ctx.Flags & FRIED_GRAYSCALE) { src += row * 2 * cols; if(ctx.Flags & FRIED_SAVEALPHA) gray_alpha_convert_dir(cols,colsPad,src,srp); else gray_x_convert_dir(cols,colsPad,src,srp); } else { src += row * 4 * cols; if(ctx.Flags & FRIED_SAVEALPHA) color_alpha_convert_dir(cols,colsPad,src,srp); else color_x_convert_dir(cols,colsPad,src,srp); } } static void reorder(sInt *dest_chunk,sInt *src_chunk,sInt cwidth) { static const sU8 psd[16] = { 0x00,0x04,0x44,0x40, 0x80,0xc0,0xc4,0x84, 0x88,0xc8,0xcc,0x8c, 0x4c,0x48,0x08,0x0c }; static const sU8 mfd[15] = { 0x40,0x04,0x08, 0x44,0x80,0xc0,0x84, 0x48,0x0c,0x4c,0x88, 0xc4,0xc8,0x8c,0xcc }; sInt nmb = cwidth / 16; sInt *g0,*g1,*g2; sInt *qbp; sInt n,k; g0 = dest_chunk; qbp = src_chunk; // macroblock DC coeffs for(sInt mb=0;mb> 4) * cwidth + (mfd[n] & 0xf)]; g1++; // block AC coeffs for(n=0;n<16;n++) { qbp = src_chunk + mb + (psd[n] >> 4) * cwidth + (psd[n] & 0xf); g2[ 1*cwidth] = qbp[1]; g2[ 2*cwidth] = qbp[2]; g2[ 8*cwidth] = qbp[3]; qbp += cwidth; g2[ 0*cwidth] = qbp[0]; g2[ 3*cwidth] = qbp[1]; g2[ 7*cwidth] = qbp[2]; g2[ 9*cwidth] = qbp[3]; qbp += cwidth; g2[ 4*cwidth] = qbp[0]; g2[ 6*cwidth] = qbp[1]; g2[10*cwidth] = qbp[2]; g2[13*cwidth] = qbp[3]; qbp += cwidth; g2[ 5*cwidth] = qbp[0]; g2[11*cwidth] = qbp[1]; g2[12*cwidth] = qbp[2]; g2[14*cwidth] = qbp[3]; g2++; } } } static sInt encodeStripe(EncodeContext &ctx,sInt cols,sInt chans,sU8 *bytes,sInt maxbytes,sInt **srp) { sInt cjs[16]; sInt cwidth = ctx.FH.ChunkWidth; sInt nchunks = (cols + cwidth - 1) / cwidth; sInt *g0,n; sU8 *byteStart = bytes; sU8 *byteEnd = bytes + maxbytes; // clear chunk positions for(sInt ch=0;ch 0) { sS16 newVal = g0[n] - g0[n-1]; g0[n] = newVal; } /*while(--n > 0) g0[n] -= g0[n-1];*/ // write number of encoded coeffs encsize = (encsize + 7) & ~7; if(encsize < 127 * 8) *bytes++ = encsize >> 2; else { sInt temp = (encsize >> 2) + 1; *bytes++ = temp & 0xff; *bytes++ = temp >> 8; } // encode the coeffs themselves if(encsize) { sInt xminit,nbs; xminit = 625 >> (qs >> 3); nbs = rlgrenc(bytes,byteEnd - bytes,g0,sMin(encsize,cwidth),xminit); if(nbs < 0) return -1; else bytes += nbs; if(encsize > cwidth) { xminit = 94 >> (qs >> 3); nbs = rlgrenc(bytes,byteEnd - bytes,g0+cwidth,encsize-cwidth,xminit); if(nbs < 0) return -1; else bytes += nbs; } } // this channel is done cjs[ch] += cwidth; } // write the chunk size sInt chunkSize = bytes - chunkSizePtr; sVERIFY(chunkSize < 65536); chunkSizePtr[0] = chunkSize & 0xff; chunkSizePtr[1] = chunkSize >> 8; } return bytes - byteStart; } static void hlbt_group1(sInt swidth,sInt so,sInt ib,sInt **srp,sBool ftop) { sInt *pa,*pb,*p0,*p1,*p2,*p3; sInt col; // normal rows only pa = srp[ib-5] + so; pb = srp[ib-4] + so; p0 = srp[ib-3] + so; p1 = srp[ib-2] + so; p2 = srp[ib-1] + so; p3 = srp[ib-0] + so; lbt4pre4x2(p0,p1,p2,p3); for(col=0;col