/*
* =====================================================================================
*
* Filename: build-table.cpp
*
* Description:
*
* Version: 1.0
* Created: 03/04/2011 22:11:22
* Revision: none
* Compiler: gcc
*
* Author: John Ryland (jryland), jryland@xiaofrog.com
* Company: InvertedLogic
*
* =====================================================================================
*/
#include <QApplication>
#include <QPixmap>
#include <QImage>
#include <stdio.h>
#include "../dct.h"
unsigned char clamp(int x)
{
if (x < 0)
return 0;
if (x > 255)
return 255;
return x;
}
void readImage(FILE *f, unsigned char *image)
{
int prevBlockDCT[64];
memset(prevBlockDCT, 0, 64*sizeof(int));
for (int j = 0; j < 32; j++) {
for (int i = 0; i < 32; i++) {
unsigned char method = 0;
unsigned char bpp = 0;
unsigned char lut_count = 0;
unsigned char min = 255;
unsigned char scale = 0;
fread(&method, 1, 1, f);
bpp = (method >> 3) & 0x7;
method = (method >> 6) & 0x3;
if ( method == 0 ) {
fread(&min, 1, 1, f);
if ( bpp == 0 ) {
for (int y = 0; y < 16; y++)
for (int x = 0; x < 16; x++) {
image[512*(j*16+y)+i*16+x] = min;
}
} else {
for (int y = 0; y < 16; y++)
for (int x = 0; x < 16; x+=(8/bpp)) {
unsigned char pix = 0;
fread(&pix, 1, 1, f);
for (int k = 0; k < (8/bpp); k++) {
image[512*(j*16+y)+i*16+x+(8/bpp)-k-1] = (pix & ((1<<bpp)-1)) + min;
pix >>= bpp;
}
}
}
} else if ( method == 1 ) {
fread(&lut_count, 1, 1, f);
unsigned char lut[256];
for (unsigned int c = 0; c < lut_count; c++) {
unsigned char ch;
fread(&ch, 1, 1, f);
lut[c] = ch;
}
if ( bpp == 0 ) {
} else {
for (int y = 0; y < 16; y++)
for (int x = 0; x < 16; x+=(8/bpp)) {
unsigned char pix = 0;
fread(&pix, 1, 1, f);
for (int k = 0; k < (8/bpp); k++) {
image[512*(j*16+y)+i*16+x+(8/bpp)-k-1] = lut[(pix & ((1<<bpp)-1))];
pix >>= bpp;
}
}
}
} else {
for (int s1 = 0; s1 < 2; s1++) {
for (int t1 = 0; t1 < 2; t1++) {
int blockDCT[64];
memset(blockDCT, 0, 64*sizeof(int));
unsigned long long zeros = 0;
fread(&zeros, 8, 1, f);
unsigned char b2;
//fread(&b2, 1, 1, f);
int bitsBuffered = 0;
unsigned long bits = 0;
for (int x = 0; x < 64; x++) {
if ( zeros & (1LL << (63-x)) ) {
blockDCT[x] = 0;
} else {
//fread(&b2, 1, 1, f);
//blockDCT[x] = (signed char)b2;
// 0x0001
#if 1
int count = 0;
// bitsBuffered -= 5;
// count += 5;
if (bitsBuffered == 0) {
fread(&b2, 1, 1, f);
bits = (bits << 8) | b2;
bitsBuffered += 8;
}
while ( ((bits & (1 << (bitsBuffered-1))) == 0) && (count < 8) ) {
count++;
bitsBuffered--;
if (bitsBuffered == 0) {
fread(&b2, 1, 1, f);
bits = (bits << 8) | b2;
bitsBuffered += 8;
}
}
int llut[8] = { -1, 1, -2, 2, -3, 3, -4, 4 };
//if ( ((bits & (1 << (bitsBuffered))) == 1) ) {
if ( count < 8 ) {
bitsBuffered--;
blockDCT[x] = llut[count];
} else {
//bitsBuffered++;// += 8;
if (bitsBuffered < 8) {
fread(&b2, 1, 1, f);
bits = (bits << 8) | b2;
bitsBuffered += 8;
}
blockDCT[x] = (signed char)((bits >> (bitsBuffered-8)) & 0xFF);
bitsBuffered -= 8;
}
#else
if (bitsBuffered < 8) {
fread(&b2, 1, 1, f);
bits <<= 8;
bits |= b2;
bitsBuffered += 8;
}
if ( bits & (1 << (bitsBuffered-1)) ) {
//if ( ((bits >> (bitsBuffered-1)) & (0xFF>>7) ) == 0x1 ) {
blockDCT[x] = -1;
bitsBuffered--;
} else if ( bits & (1 << (bitsBuffered-2)) ) {
//} else if ( ((bits >> ((unsigned)bitsBuffered-2)) & (0xFF>>6) ) == 0x1 ) {
blockDCT[x] = (int)1;
bitsBuffered -= 2;
//} else if ( bits & (1 << (bitsBuffered-3)) ) {
} else if ( ((bits >> (bitsBuffered-3)) & (0x7) ) == 0x1 ) {
blockDCT[x] = -2;
bitsBuffered -= 3;
//} else if ( bits & (1 << (bitsBuffered-4)) ) {
} else if ( ((bits >> (bitsBuffered-4)) & (0xF) ) == 0x1 ) {
blockDCT[x] = 2;
bitsBuffered -= 4;
//} else if ( bits & (1 << (bitsBuffered-5)) ) {
} else if ( ((bits >> (bitsBuffered-5)) & (0xFF>>3) ) == 0x1 ) {
blockDCT[x] = -3;
bitsBuffered -= 5;
//} else if ( bits & (1 << (bitsBuffered-6)) ) {
} else if ( ((bits >> (bitsBuffered-6)) & (0xFF>>2) ) == 0x1 ) {
blockDCT[x] = 3;
bitsBuffered -= 6;
} else if ( ((bits >> (bitsBuffered-7)) & (0xFF>>1) ) == 0x1 ) {
blockDCT[x] = -4;
bitsBuffered -= 7;
} else if ( ((bits >> (bitsBuffered-8)) & 0xFF) == 0x1 ) {
blockDCT[x] = 4;
bitsBuffered -= 8;
} else {
while (bitsBuffered < 16) {
fread(&b2, 1, 1, f);
bits <<= 8;
bits |= b2;
bitsBuffered += 8;
}
//blockDCT[x] = bits & (0xFF << (bitsBuffered-16));
blockDCT[x] = (signed char)((bits >> (bitsBuffered-16)) & 0xFF);
//if ( blockDCT[x] > 128 )
// blockDCT[x] = blockDCT[x] - 256;
bitsBuffered -= 16;
}
#endif
}
}
/*
fread(&b2, 1, 1, f);
if (b2 != 0xAB)
{
if (b2 != 0xFF) {
printf("framing error %i != %i\n", b2, 0xFF);
exit(-1);
}
fread(&b2, 1, 1, f);
if (b2 != 0xAB) {
printf("framing error %i != %i\n", b2, 0xAB);
exit(-1);
}
}
*/
blockDCT[0] += prevBlockDCT[0];
blockDCT[2] += blockDCT[1];
for (int x = 0; x < 64; x++)
prevBlockDCT[x] = blockDCT[x];
int pixels[64];
decodeDCT(blockDCT, pixels);
for (int y = 0; y < 8; y++)
for (int x = 0; x < 8; x++)
image[512*(j*16+y+s1*8)+i*16+x+t1*8] = clamp(pixels[y*8+x]);
}
}
/*
for (int s1 = 0; s1 < 2; s1++) {
for (int t1 = 0; t1 < 2; t1++) {
int blockDCT[64];
memset(blockDCT, 0, 64*sizeof(int));
unsigned char count;
fread(&count, 1, 1, f);
for (int x = 0; x < count; x++) {
//for (int x = 0; x < 64; x++) {
signed int ch;
fread(&ch, 4, 1, f);
blockDCT[x] = ch;
}
int pixels[64];
decodeDCT(blockDCT, pixels);
for (int y = 0; y < 8; y++)
for (int x = 0; x < 8; x++)
image[512*(j*16+y+s1*8)+i*16+x+t1*8] = clamp(pixels[y*8+x]);
}
}
*/
/*
fread(&min, 1, 1, f);
fread(&scale, 1, 1, f);
for (int y = 0; y < 16; y++)
for (int x = 0; x < 16; x+=2) {
unsigned char pix1;
unsigned char pix2;
fread(&pix1, 1, 1, f);
pix2 = pix1 & 0xF;
pix1 >>= 4;
pix2 <<= scale;
pix1 <<= scale;
pix2 += min;
pix1 += min;
image[512*(j*16+y)+i*16+x+0] = pix1;
image[512*(j*16+y)+i*16+x+1] = pix2;
}
*/
}
}
}
}
/*
unsigned char method = 0;
unsigned char bpp = 0;
unsigned char lut_count = 0;
if ( range < 16 ) {
method = (method << 6) | (bpp << 3) | lut_count;
fwrite(&method, 1, 1, f);
fwrite(&min, 1, 1, f);
//fwrite(&scale, 1, 1, f);
if ( bpp == 0 ) {
} else {
for (int y = 0; y < 16; y++)
for (int x = 0; x < 16; x+=(8/bpp)) {
unsigned char pix = 0;
for (int k = 0; k < (8/bpp); k++)
pix = (pix << bpp) | (image[512*(j*16+y)+i*16+x+k] - min);
fwrite(&pix, 1, 1, f);
}
}
} else if ( distinctValueCount < 16 ) {
method = 1;
//lut_count = (distinctValueCount + 1) / 2;
method = (method << 6) | (bpp << 3) | lut_count;
fwrite(&method, 1, 1, f);
fwrite(&distinctValueCount, 1, 1, f);
unsigned char lut[256];
unsigned char t = 0;
for (unsigned int c = 0; c <= 255; c++) {
if ( count[c] ) {
unsigned char ch = c;
fwrite(&ch, 1, 1, f);
lut[c] = t;
t++;
}
}
if ( bpp == 0 ) {
} else {
for (int y = 0; y < 16; y++)
for (int x = 0; x < 16; x+=(8/bpp)) {
unsigned char pix = 0;
for (int k = 0; k < (8/bpp); k++)
pix = (pix << bpp) | lut[image[512*(j*16+y)+i*16+x+k]];
fwrite(&pix, 1, 1, f);
}
}
method = 2;
method = (method << 6) | (bpp << 3) | lut_count;
fwrite(&method, 1, 1, f);
fwrite(&min, 1, 1, f);
fwrite(&scale, 1, 1, f);
for (int y = 0; y < 16; y++)
for (int x = 0; x < 16; x+=2) {
unsigned char pix1 = image[512*(j*16+y)+i*16+x+0];
unsigned char pix2 = image[512*(j*16+y)+i*16+x+1];
pix1 -= min;
pix1 >>= scale;
pix2 -= min;
pix2 >>= scale;
pix1 = (pix1 << 4) | pix2;
fwrite(&pix1, 1, 1, f);
}
}
*/
void dumpImage(int s, unsigned char *image, int depth)
{
QImage outputImage(s, s, QImage::Format_RGB888);
for (int y = 0; y < s; y++) {
for (int x = 0; x < s; x++) {
unsigned char p = image[y*s+x];
unsigned int p2 = p;
p2 = (p2 << 16) | (p2 << 8) | p2;
outputImage.setPixel(x, y, p2);
}
}
outputImage.save(QString("output%1.png").arg(depth));
}
#include <math.h>
void compareImage(int s, unsigned char *image)
{
unsigned int totalDiff = 0;
QImage originalImage("original.png");
QImage outputImage(s, s, QImage::Format_RGB888);
int diffCounts[256];
memset(diffCounts, 0, 256*sizeof(int));
for (int y = 0; y < s; y++) {
for (int x = 0; x < s; x++) {
unsigned char p = image[y*s+x];
unsigned char o = originalImage.pixel(x, y) & 0xFF;
int px2 = p - o;
//signed char py2 = px2 + ;
unsigned char pi2 = px2 + 128;
printf("%i,", px2);
unsigned int p2 = (pi2 << 16) | (pi2 << 8) | pi2;
outputImage.setPixel(x, y, p2);
totalDiff += (int)fabs(px2);
diffCounts[px2+128]++;
}
}
FILE *fd = fopen("diff.img", "w");
for (int y = 0; y < s; y++) {
for (int x = 0; x < s; x++) {
unsigned char p = image[y*s+x];
unsigned char o = originalImage.pixel(x, y) & 0xFF;
signed char px2 = (signed char)(p - o);
if ( c > -4 && c <= 4 ) {
int llut[9] = { 7,5,3,1,0,2,4,6,8 };
int t = llut[c + 4];
bitsBuffered += t;
bits <<= t;
bits |= 1;
} else {
bitsBuffered += 16;
bits <<= 16;
bits |= (unsigned char)(c & 0xFF);
}
while ( bitsBuffered >= 8 ) {
unsigned long long b = (bits >> (bitsBuffered - 8)) & 0xFF;
unsigned char b2 = (unsigned char)b;
fwrite(&b2, 1, 1, f);
bitsBuffered -= 8;
//bits >>= 8;
}
fwrite(&px2, 1, 1, fd);
}
}
fclose(fd);
for (int i = -16; i < 17; i++) {
printf(" diff counts [%i] = %i\n", i, diffCounts[i+128]);
}
outputImage.save("difference.png");
outputImage.save("difference.bmp");
outputImage.save("difference.jpg");
outputImage.save("difference.tif");
printf("total diff: %i\n", totalDiff);
printf("average diff: %i\n", totalDiff / (512*512));
}
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
printf("starting\n");
initTables();
const int size = 512*512;
unsigned char *image = (unsigned char *)malloc(size);
printf("alloced mem\n");
memset(image, 0, size);
printf("zeroed mem\n");
FILE *f = fopen("blah.out", "r");
//readTree(f, &headNode, 0, 512, 512, true);
readImage(f, image);
fclose(f);
printf("read tree\n");
dumpImage(512, image, 0);
compareImage(512, image);
return 0;//app.exec();
}