i really can't understand what's wrong in here.
i placed this code
for (ptr=0; ptr<w*h*3; ptr++) {
if (bmp[ptr]<0 or bmp[ptr]>255) { printf ("%7d: %12d\n", ptr,
(unsigned int)bmp[ptr]); }
}
after every loop to track the memory contents and i discovered that
normalizing and denormalizing are working. but what i can't understand is
that if i place it after the deblurring loop i get huge and even negatives
(even if bmp[] is unsigned long) values!
what's funny is that if i turn off the normalization/denormalization
process, the blurring/deblurring filters work correctly.
in case, this is the source (try to feed it a 24 bit uncompressed bmp file
with just a coloured text on a flat white bg):
// Simplify 0.0.7
// (C) 2003 CAFxX
#include <stdio.h>
#include <stdlib.h>
#include "Simplify_private.h" // DEV-CPP version informations
using namespace std;
// GLOBALs
unsigned short c; //Components counter
unsigned int x; //X-axis pixel coordinate counter
unsigned int y; //Y-axis pixel coordinate counter
int rx; //X-axis spreading distance counter
int ry; //Y-axis spreading distance counter
unsigned int w; //Source image width
unsigned int h; //Source image height
unsigned short s; //Spreading factor
unsigned long max; //Normalizing MAX value
unsigned long min; //Normalizing MIN value
unsigned long dummybytes; //Number of dummy bytes per line
unsigned long ptr; //*bmp array pseudo-pointer
FILE *fp1; //Input file pointer
FILE *fp2; //Output file pointer
unsigned long *bmp; //Memory pointer
void test() {
if ((fp1 = fopen("test.bmp", "rb")) == NULL) { exit(2); }
if ((fp2 = fopen("out.bmp", "wb")) == NULL) { exit(1); }
fseek (fp1, 54, SEEK_SET);
// BLURRING LOOP - WORKING
for (y=0; y<h; y++) {
printf("%3d\b\b\b",y);
for (x=0; x<w; x++) {
for (c=0; c<3; c++) {
unsigned short byte = fgetc(fp1);
bmp[(x+y*w)*3+c] += byte; // #1 (see TODO)
// bmp[(x+y*w)*3+c] += (unsigned long)byte * (unsigned
long)s; // this has to be tested
for (rx=-s; rx<=s; rx++) {
for (ry=1; ry<=s; ry++) {
if (!((x+rx < 0) or (x+rx >= w) or (y+ry >= h)))
{ // to avoid page fault
bmp[(x+rx+(y+ry)*w)*3+c] += byte;
}
}
}
}
}
fseek(fp1, dummybytes, SEEK_CUR);
}
fseek(fp1, 54, SEEK_SET);
for (ptr=0; ptr<w*3; ptr++) {
bmp[ptr] = fgetc(fp1);
}
// NORMALIZING LOOPs
// FIND HIGHEST/LOWEST VALUES TO BE USED IN 0-255 NORMALIZATION -
PROBABLY WORKING
max = min = bmp[0];
for (ptr=w*3; ptr<w*h*3; ptr++) {
if (max < bmp[ptr]) {
max = bmp[ptr];
} else if (min > bmp[ptr]) {
min = bmp[ptr];
}
}
printf ("%10d %10d\n", max, min);
max -= min;
// NORMALIZE VALUES - WORKKING
for (ptr=w*3; ptr<w*h*3; ptr++) {
//bmp[ptr] = (unsigned long)((float)(bmp[ptr] - min) /
(float)max * (float)255);
bmp[ptr] -= min;
bmp[ptr] <<= 8;
bmp[ptr] /= max;
}
//DENORMALIZE VALUES - WORKING
for (ptr=w*3; ptr<w*h*3; ptr++) {
bmp[ptr] *= max;
bmp[ptr] >>= 8; // it should be /255, but i think it will work
bmp[ptr] += min;
}
// DEBLURRING LOOP - WORKING
for (y=0; y<h; y++) {
printf("%3d\b\b\b",y);
for (x=0; x<w; x++) {
for (c=0; c<3; c++) {
for (rx=-s; rx<=s; rx++) {
for (ry=1; ry<=s; ry++) {
if (!((x+rx < 0) or (x+rx >= w) or (y+ry >= h)))
{ // to avoid page fault
bmp[(x+rx+(y+ry)*w)*3+c] -= bmp[(x+y*w)*3+c];
}
}
}
}
}
}
// OUTPUTTING LOOPs
// COPY SOURCE IMAGE BMP HEADER - WORKING
fseek(fp1, 0, SEEK_SET);
for (ptr=0; ptr<54; ptr++) {
fputc(fgetc(fp1),fp2);
}
// WRITE DATA CONTAINED IN THE BMP ARRAY IN THE SAME ORDER THEY WERE
READ - WORKING
for (ptr=0; ptr<w*h*3; ptr++) {
fputc (bmp[ptr], fp2);
}
fclose(fp1);
fclose(fp2);
}
long flen (FILE *fp)
{
long ptr = ftell(fp);
fseek(fp, 0, SEEK_END);
long lenght = ftell(fp);
fseek(fp, ptr, SEEK_SET);
return lenght;
}
int main(int argc, char *argv[]) {
printf("Simplify ");
printf(VER_STRING);
printf("\n(C) 2003 CAFxX\n\n");
// COMMAND LINE PARSING IS JUST EXPERIMENTAL AND HAS NEVER BEEN TESTED
// SYNTAX WOULD BE
// SIMPLIFY INPUT_FILE OUTPUT_FILE SPREADING_FACTOR [D | E]
// ALL PARAMETERS ARE MANDATORY. LAST PARAMETER IS D(ECODING) | E(NCODING).
// E.G: simplify input.bmp output.bmp 10 e
if (argc == 5) {
if ((fp1 = fopen(argv[2], "rb")) == NULL) { exit(2); }
if ((fp2 = fopen(argv[3], "wb")) == NULL) { exit(1); }
s = atoi(argv[4]);
if (argv[5] == "D" or argv[4] == "d") { /*decode();*/ }
else if (argv[5] == "E" or argv[4] == "e") { /*encode();*/ }
exit(0);
} else if (argc == 1) {
// COLLECTING IMAGE SIZE
printf("Input file must be a 24-bit uncompressed Windows BMP
file!\nSource image width > ");
scanf("%d",&w);
if (w <= 0) { exit(0); } // EXIT IF IMAGE DIMENSIONS ARE NOT VALID
printf("Source image height > ");
scanf("%d",&h);
if (h <= 0) { exit(0); }
// COLLECTING ENCODING SETTINGS
printf("Spreading factor > ");
scanf("%d",&s);
// DUMMY BYTES PER LINE
if ((fp1 = fopen("test.bmp", "rb")) == NULL) { exit(2); }
dummybytes = (flen(fp1) - h * w * 3 + 54) / h;
fclose(fp1);
// ALLOCATE MEMORY AND START PROCESSING
bmp = (unsigned long*)malloc(sizeof(unsigned long)*w*h*3);
if (bmp == NULL) { exit(3); }
test();
free(bmp);
system ("pause");
return 0;
} else {
printf ("Wrong parameter number");
exit(4);
}
}
thanks in advance to anyone that will help.
"CAFxX" <ca***@n-side.it> ha scritto nel messaggio
news:bo**********@news.wplus.net...
i'm writing a program that executes some calculations on a bitmap loaded
in memory.
these calculation ends up with pixel wth values far over 255, but i need
them to be between 0 and 255 since i got to write them in a bmp file (in
which RGB values are limited to 8 bits per channel). so i need to have
them scaled down.
first of all i find the highest and lowest of those values:(keep in mind
that max, min, bmp[], ptr are ulong and w, h are uint):
// FIND HIGHEST/LOWEST VALUES TO BE USED IN 0-255 NORMALIZATION
max = 0; min = 0-1;
for (int ptr=0; ptr<w*h*3; ptr++) {
if (max < bmp[ptr]) {
max = bmp[ptr];
} else if (min > bmp[ptr]) {
min = bmp[ptr];
}
}
then i normalize everything to 255:
// NORMALIZE VALUES
for (int ptr=0; ptr<w*h*3; ptr++) {
bmp[ptr] = (unsigned long)((float)(bmp[ptr] - min) / (float)max *
(float)255);
}
at this point, everything is alright. if i write in a bmp file the
contents of the array i get what i expected.
but as soon as i denormalize and apply the inverse of the calculations i
did before (i tested them separately: without normalization/denormalization
they work fine)
//DENORMALIZE VALUES
for (int ptr=0; ptr<w*h*3; ptr++) {
bmp[ptr] = (unsigned long)((float)bmp[ptr] / (float)255 * (float)max) +
min; }
then i write down the content of the array:
// OUTPUTTING LOOPs
// COPY SOURCE IMAGE BMP HEADER - WORKING
fseek(fp1, 0, SEEK_SET);
for (int i=0; i<54; i++) {
fputc(fgetc(fp1),fp2);
}
// WRITE DATA CONTAINED IN THE BMP ARRAY IN THE SAME ORDER THEY WERE
READ - WORKING
for (int ptr=0; ptr<w*h*3; ptr++) {
fputc ((unsigned int)bmp[ptr], fp2);
}
but the bitmap i end up with it's a mess of random pixels.
i think i'm doing something wrong in the data type conversion of the
denormalization loop. anyone knows why? i do thank you in advance.
p.s. if you want the full source of the program go to
sourceforge.net/projects/simplify. the function you got to point at is
void test ()