/* costs per 4 pixels: (# = black) 1 bit: ---- 4 bits: #--- ##-- --## #### 5 bits: ---# #-## -### -#-- --#- 6 bits: #-#- -##- ###- #--# -#-# ##-# */ #include void LogoPackBits(unsigned char *srcp, unsigned char *destp) { unsigned int destbit = 0; unsigned int destvalue = 0; unsigned int d = 0; for (unsigned int s=0; s<1664; s++) { if (srcp[s]) destvalue |= 1<> j & 0xF]; outbitcnt += lh.bits; for (int b=lh.bits-1; b>=0; b--) { data_out |= (lh.value >> b & 1) << outbit; if (outbit == 0) { if (outbitcnt <= 156*8) { *dst++ = data_out >> 0; *dst++ = data_out >> 8; *dst++ = data_out >> 16; *dst++ = data_out >> 24; } outbit = 31; data_out = 0; } else { outbit--; } } } } if (outbit != 31) { if (outbitcnt <= 156*8) { *dst++ = data_out >> 0; *dst++ = data_out >> 8; *dst++ = data_out >> 16; *dst++ = data_out >> 24; } } return 156*8 - outbitcnt; }; void LogoDiff(unsigned char *srcp, unsigned char *dstp) { unsigned int *intp_dst = (unsigned int *)dstp; *intp_dst++ = 0xD0 << 8 | 0x80 | 2; // header unsigned short *shortp_dst = (unsigned short *)intp_dst; unsigned short *shortp_src = (unsigned short *)srcp; unsigned short prev = 0; for (unsigned int i=0; i<0xD0; i+=2) { *shortp_dst++ = *shortp_src - prev; prev = *shortp_src++; } } int LogoConvert(unsigned char *srcp, unsigned char *dstp, unsigned char white) { // convert to tiles unsigned char tiles[1664]; for (int ty=0; ty<2; ty++) { for (int y=0; y<8; y++) { for (int tx=0; tx<13; tx++) { for (int x=0; x<8; x++) { tiles[(ty*13 + tx)*64 + y*8 + x] = (*srcp++ == white) ? 0 : 1; } } } } // bitpack unsigned char bitpacked[1664/8]; LogoPackBits(tiles, bitpacked); // diff unsigned char diffed[4 + 1664/8]; LogoDiff(bitpacked, diffed); // compress int r = LogoCompress(diffed, dstp); if (r < 0) { fprintf(stderr, "Compressed logo is %u bit(s) too big. Please simplify.\n", -r); return -1; } return 0; }