problems with data type conversion (maybe)

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • CAFxX

    problems with data type conversion (maybe)

    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)(b mp[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)bm p[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 ()


  • Ron Natalie

    #2
    Re: problems with data type conversion (maybe)


    "CAFxX" <cafxx@n-side.it> wrote in message news:bornt2$2l0 $1@news.wplus.n et...
    [color=blue]
    > // FIND HIGHEST/LOWEST VALUES TO BE USED IN 0-255 NORMALIZATION
    > max = 0; min = 0-1;[/color]
    0-1? How about just -1? And unless min is unsigned, you don't
    even want to do that. Th easiest way is just to seed min and max
    with the first pixel value.

    min = bmp[0];
    max = bmp[0]
    for(int ptr = 1; ...

    [color=blue]
    > // NORMALIZE VALUES
    > for (int ptr=0; ptr<w*h*3; ptr++) {
    > bmp[ptr] = (unsigned long)((float)(b mp[ptr] - min) / (float)max *
    > (float)255);[/color]

    This calculation is wrong. You'll get bizarre results if min isn't zero.\
    You don't even need to do float provided that the following won't overflow.
    bmp[ptr] = (bmp[ptr] - min)*255 / (max - min)
    You don't tell me what the types of min, max, and bmp are so I can't make a decision.
    [color=blue]
    > bmp[ptr] = (unsigned long)((float)bm p[ptr] / (float)255 * (float)max) + min;[/color]

    Likewise
    bmp[ptr] = bmp[ptr] *(max - min) / 255 + min;
    Provided min and max are still the same value they were before.

    [color=blue]
    > // 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);[/color]

    Hopefully, you are doing this with the normalized bmp values as fputc. The cast is spurious.


    Comment

    • CAFxX

      #3
      Re: problems with data type conversion (maybe)

      this is the complete source of my program.
      in my first post i forgot to paste the line
      max -= min;
      but it was already there.
      are your instructions still valid? thanks for your help.

      #include <stdio.h>
      #include <stdlib.h>
      #include "Simplify_priva te.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 = 0-1; //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() {
      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 ("%d %d\n", max, min);
      max -= min;
      // NORMALIZE VALUES
      for (ptr=w*3; ptr<w*h*3; ptr++) {
      bmp[ptr] = (unsigned int)((float)(bm p[ptr] - min) / (float)max *
      (float)255);
      }
      //DENORMALIZE VALUES
      for (ptr=w*3; ptr<w*h*3; ptr++) {
      bmp[ptr] = (unsigned long)((float)bm p[ptr] / (float)255 *
      (float)max) + min;
      }
      max=0; min=0-1;
      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 ("%d %d\n", max, 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);
      }

      "Ron Natalie" <ron@sensor.com > ha scritto nel messaggio
      news:3fb12003$0 $202$9a6e19ea@n ews.newshosting .com...[color=blue]
      >
      > "CAFxX" <cafxx@n-side.it> wrote in message[/color]
      news:bornt2$2l0 $1@news.wplus.n et...[color=blue]
      >[color=green]
      > > // FIND HIGHEST/LOWEST VALUES TO BE USED IN 0-255 NORMALIZATION
      > > max = 0; min = 0-1;[/color]
      > 0-1? How about just -1? And unless min is unsigned, you don't
      > even want to do that. Th easiest way is just to seed min and max
      > with the first pixel value.
      >
      > min = bmp[0];
      > max = bmp[0]
      > for(int ptr = 1; ...
      >
      >[color=green]
      > > // NORMALIZE VALUES
      > > for (int ptr=0; ptr<w*h*3; ptr++) {
      > > bmp[ptr] = (unsigned long)((float)(b mp[ptr] - min) / (float)max *
      > > (float)255);[/color]
      >
      > This calculation is wrong. You'll get bizarre results if min isn't zero.\
      > You don't even need to do float provided that the following won't[/color]
      overflow.[color=blue]
      > bmp[ptr] = (bmp[ptr] - min)*255 / (max - min)
      > You don't tell me what the types of min, max, and bmp are so I can't make[/color]
      a decision.[color=blue]
      >[color=green]
      > > bmp[ptr] = (unsigned long)((float)bm p[ptr] / (float)255 * (float)max) +[/color][/color]
      min;[color=blue]
      >
      > Likewise
      > bmp[ptr] = bmp[ptr] *(max - min) / 255 + min;
      > Provided min and max are still the same value they were before.
      >
      >[color=green]
      > > // WRITE DATA CONTAINED IN THE BMP ARRAY IN THE SAME ORDER THEY WERE[/color][/color]
      READ -[color=blue][color=green]
      > > WORKING
      > > for (int ptr=0; ptr<w*h*3; ptr++) {
      > > fputc ((unsigned int)bmp[ptr], fp2);[/color]
      >
      > Hopefully, you are doing this with the normalized bmp values as fputc.[/color]
      The cast is spurious.[color=blue]
      >
      >[/color]


      Comment

      • CAFxX

        #4
        Re: problems with data type conversion (maybe)

        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_priva te.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)(b mp[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("Simplif y ");
        printf(VER_STRI NG);
        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_FACTO R [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("Spreadi ng 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(si zeof(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" <cafxx@n-side.it> ha scritto nel messaggio
        news:bornt2$2l0 $1@news.wplus.n et...[color=blue]
        > i'm writing a program that executes some calculations on a bitmap loaded[/color]
        in[color=blue]
        > 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[/color]
        them[color=blue]
        > 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)(b mp[ptr] - min) / (float)max *
        > (float)255);
        > }
        >
        > at this point, everything is alright. if i write in a bmp file the[/color]
        contents[color=blue]
        > of the array i get what i expected.
        > but as soon as i denormalize and apply the inverse of the calculations i[/color]
        did[color=blue]
        > before (i tested them separately: without normalization/denormalization[/color]
        they[color=blue]
        > work fine)
        >
        > //DENORMALIZE VALUES
        > for (int ptr=0; ptr<w*h*3; ptr++) {
        > bmp[ptr] = (unsigned long)((float)bm p[ptr] / (float)255 * (float)max) +[/color]
        min;[color=blue]
        > }
        >
        > 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[/color]
        READ -[color=blue]
        > 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[/color]
        void[color=blue]
        > test ()
        >
        >[/color]


        Comment

        • CAFxX

          #5
          Re: problems with data type conversion (maybe)

          hmmm, posted the wrong loop[color=blue]
          > i really can't understand what's wrong in here.
          > i placed this code[/color]
          this is the right one:
          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]); }
          }

          "CAFxX" <cafxx@n-side.it> ha scritto nel messaggio
          news:bp3fas$2ck 1$1@news.wplus. net...[color=blue]
          > 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_priva te.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)(b mp[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("Simplif y ");
          > printf(VER_STRI NG);
          > 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_FACTO R [D | E]
          > // ALL PARAMETERS ARE MANDATORY. LAST PARAMETER IS D(ECODING) |[/color]
          E(NCODING).[color=blue]
          > // 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("Spreadi ng 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(si zeof(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" <cafxx@n-side.it> ha scritto nel messaggio
          > news:bornt2$2l0 $1@news.wplus.n et...[color=green]
          > > i'm writing a program that executes some calculations on a bitmap loaded[/color]
          > in[color=green]
          > > 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[/color]
          > them[color=green]
          > > 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)(b mp[ptr] - min) / (float)max *
          > > (float)255);
          > > }
          > >
          > > at this point, everything is alright. if i write in a bmp file the[/color]
          > contents[color=green]
          > > of the array i get what i expected.
          > > but as soon as i denormalize and apply the inverse of the calculations i[/color]
          > did[color=green]
          > > before (i tested them separately: without normalization/denormalization[/color]
          > they[color=green]
          > > work fine)
          > >
          > > //DENORMALIZE VALUES
          > > for (int ptr=0; ptr<w*h*3; ptr++) {
          > > bmp[ptr] = (unsigned long)((float)bm p[ptr] / (float)255 * (float)max) +[/color]
          > min;[color=green]
          > > }
          > >
          > > 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[/color]
          > READ -[color=green]
          > > 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[/color]
          > void[color=green]
          > > test ()
          > >
          > >[/color]
          >
          >[/color]


          Comment

          • Ron Natalie

            #6
            Re: problems with data type conversion (maybe)


            "CAFxX" <cafxx@n-side.it> wrote in message news:bp3fec$2d3 5$1@news.wplus. net...
            [color=blue]
            > if (bmp[ptr]<0 or bmp[ptr]>255) { printf ("%7d: %12d\n", ptr,
            > (unsigned int)bmp[ptr]); }[/color]

            The unsigned int cast doesn't do anything useful. %d always expects an int.


            Comment

            • Ron Natalie

              #7
              Re: problems with data type conversion (maybe)


              "CAFxX" <cafxx@n-side.it> wrote in message news:bp3fas$2ck 1$1@news.wplus. net...
              [color=blue]
              > for (ptr=w*3; ptr<w*h*3; ptr++) {
              > //bmp[ptr] = (unsigned long)((float)(b mp[ptr] - min) /
              > (float)max * (float)255);
              > bmp[ptr] -= min;
              > bmp[ptr] <<= 8;
              > bmp[ptr] /= max;
              > }[/color]

              You still want (max-min) as a divisor as I pointed out before.
              [color=blue]
              > //DENORMALIZE VALUES - WORKING
              > for (ptr=w*3; ptr<w*h*3; ptr++) {
              > bmp[ptr] *= max;[/color]

              Same here.
              [color=blue]
              > 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];
              > }
              > }
              > }
              > }
              > }[/color]

              The above looks bogus. Are you trying to implement an unsharp mask? You most likely
              need two buffers, the resultant output pixel is hosed by the modification you make.


              Comment

              • CAFxX

                #8
                Re: problems with data type conversion (maybe)

                i already placed the max-min:
                // NORMALIZING LOOPs
                .....
                max -= min;
                [color=blue]
                > The above looks bogus. Are you trying to implement an unsharp mask?[/color]
                You most likely[color=blue]
                > need two buffers, the resultant output pixel is hosed by the modification[/color]
                you make.

                no it's not an unsharp mask (at least that wasn't my intention, i don't know
                how the unsharp mask filter works) the deblurring loop is supposed to be the
                reverse filter of the blurring loop above.
                it works this way:
                a pixel is read from the source file.
                its value is ADDED to its position in memory (§)
                its value is ADDED to all the pixel ranging (provided x, y are the pixel's
                coordinates): from (x-s, y+1) to (x+s, y+s) where s is the spreading factor
                because of these sums the final values are likely above 255 so they have to
                be normalized to 255.
                this is encoding. now, for decoding:
                all the pixels are read and placed in memory
                the pixels' values are denormalized.
                for every pixel, starting from the first that was encoded,
                its value is SUBTRACTED to all the pixel ranging (provided x, y are the
                pixel's coordinates): from (x-s, y+1) to (x+s, y+s) where s is the spreading
                factor.
                so we end up with the original image (because of §).




                "Ron Natalie" <ron@sensor.com > ha scritto nel messaggio
                news:3fb5454b$0 $75659$9a6e19ea @news.newshosti ng.com...[color=blue]
                >
                > "CAFxX" <cafxx@n-side.it> wrote in message[/color]
                news:bp3fas$2ck 1$1@news.wplus. net...[color=blue]
                >[color=green]
                > > for (ptr=w*3; ptr<w*h*3; ptr++) {
                > > //bmp[ptr] = (unsigned long)((float)(b mp[ptr] - min) /
                > > (float)max * (float)255);
                > > bmp[ptr] -= min;
                > > bmp[ptr] <<= 8;
                > > bmp[ptr] /= max;
                > > }[/color]
                >
                > You still want (max-min) as a divisor as I pointed out before.
                >[color=green]
                > > //DENORMALIZE VALUES - WORKING
                > > for (ptr=w*3; ptr<w*h*3; ptr++) {
                > > bmp[ptr] *= max;[/color]
                >
                > Same here.
                >[color=green]
                > > 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] -=[/color][/color]
                bmp[(x+y*w)*3+c];[color=blue][color=green]
                > > }
                > > }
                > > }
                > > }
                > > }[/color]
                >
                > The above looks bogus. Are you trying to implement an unsharp mask?[/color]
                You most likely[color=blue]
                > need two buffers, the resultant output pixel is hosed by the modification[/color]
                you make.[color=blue]
                >
                >[/color]


                Comment

                • CAFxX

                  #9
                  Re: problems with data type conversion (maybe)

                  @ ron natalie
                  have you tryed to feed it a simple bmp image? for testing i use a 400x300
                  bitmap with a flat white bg and the text "TEST" on it, with letters coloured
                  respectively black, red, green, blue.

                  "CAFxX" <cafxx@n-side.it> ha scritto nel messaggio
                  news:bp3i51$2pt 3$1@news.wplus. net...[color=blue]
                  > i already placed the max-min:
                  > // NORMALIZING LOOPs
                  > ....
                  > max -= min;
                  >[color=green]
                  > > The above looks bogus. Are you trying to implement an unsharp mask?[/color]
                  > You most likely[color=green]
                  > > need two buffers, the resultant output pixel is hosed by the[/color][/color]
                  modification[color=blue]
                  > you make.
                  >
                  > no it's not an unsharp mask (at least that wasn't my intention, i don't[/color]
                  know[color=blue]
                  > how the unsharp mask filter works) the deblurring loop is supposed to be[/color]
                  the[color=blue]
                  > reverse filter of the blurring loop above.
                  > it works this way:
                  > a pixel is read from the source file.
                  > its value is ADDED to its position in memory (§)
                  > its value is ADDED to all the pixel ranging (provided x, y are the pixel's
                  > coordinates): from (x-s, y+1) to (x+s, y+s) where s is the spreading[/color]
                  factor[color=blue]
                  > because of these sums the final values are likely above 255 so they have[/color]
                  to[color=blue]
                  > be normalized to 255.
                  > this is encoding. now, for decoding:
                  > all the pixels are read and placed in memory
                  > the pixels' values are denormalized.
                  > for every pixel, starting from the first that was encoded,
                  > its value is SUBTRACTED to all the pixel ranging (provided x, y are the
                  > pixel's coordinates): from (x-s, y+1) to (x+s, y+s) where s is the[/color]
                  spreading[color=blue]
                  > factor.
                  > so we end up with the original image (because of §).
                  >
                  >
                  >
                  >
                  > "Ron Natalie" <ron@sensor.com > ha scritto nel messaggio
                  > news:3fb5454b$0 $75659$9a6e19ea @news.newshosti ng.com...[color=green]
                  > >
                  > > "CAFxX" <cafxx@n-side.it> wrote in message[/color]
                  > news:bp3fas$2ck 1$1@news.wplus. net...[color=green]
                  > >[color=darkred]
                  > > > for (ptr=w*3; ptr<w*h*3; ptr++) {
                  > > > //bmp[ptr] = (unsigned long)((float)(b mp[ptr] - min) /
                  > > > (float)max * (float)255);
                  > > > bmp[ptr] -= min;
                  > > > bmp[ptr] <<= 8;
                  > > > bmp[ptr] /= max;
                  > > > }[/color]
                  > >
                  > > You still want (max-min) as a divisor as I pointed out before.
                  > >[color=darkred]
                  > > > //DENORMALIZE VALUES - WORKING
                  > > > for (ptr=w*3; ptr<w*h*3; ptr++) {
                  > > > bmp[ptr] *= max;[/color]
                  > >
                  > > Same here.
                  > >[color=darkred]
                  > > > 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 >=[/color][/color][/color]
                  h)))[color=blue][color=green][color=darkred]
                  > > > { // to avoid page fault
                  > > > bmp[(x+rx+(y+ry)*w) *3+c] -=[/color][/color]
                  > bmp[(x+y*w)*3+c];[color=green][color=darkred]
                  > > > }
                  > > > }
                  > > > }
                  > > > }
                  > > > }[/color]
                  > >
                  > > The above looks bogus. Are you trying to implement an unsharp mask?[/color]
                  > You most likely[color=green]
                  > > need two buffers, the resultant output pixel is hosed by the[/color][/color]
                  modification[color=blue]
                  > you make.[color=green]
                  > >
                  > >[/color]
                  >
                  >[/color]


                  Comment

                  Working...