Click here to Skip to main content
15,886,788 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
I'm trying to use lookup table for pixel computation in openGL with input image, here's my lookup table :
float  pix_scaling [256];
static void scaling(void)
{
    for (int i = 0; i < 256; i++) 
        pix_scaling[i] = (i * 0.5) + 25;  
 }
I call both function in my main loop, but I can't get the result output, it's just blank black and somehow no error in terminal.

What I have tried:

I call my lookup table in other function :

unsigned char       * image;
unsigned char       * image1;

static void makerShift(){
unsigned char *p, *p1;
float r, g, b;

    if(image1 == NULL) {
        image1 = (unsigned char *)malloc(width*height*4);
        if(image1 == NULL) exit(0);

p  = image;
p1 = image1;

for(int i = 0; i < height*width; i++) {
    r = pix_scaling[p[0]]; // here
    g = pix_scaling[p[1]];
    b = pix_scaling[p[2]];

    //.. other computation process..//

    //to set maximum and minimum pixel value
      if   (r < 0) *(p1+0) = 0;
      else if(r > 255) *(p1+0) = 255;
      else *(p1+0) = r;
        
      if   (g < 0) *(p1+1) = 0;
      else if(g > 255) *(p1+1) = 255;
      else *(p1+1) = g;
        
      if   (b < 0) *(p1+2) = 0;
      else if(b > 255) *(p1+2) = 255;
      else *(p1+2) = b;

      p +=4;
      p1 +=4;
}
Image comes from this :
image = SOIL_load_image("Images/sample.jpg", &width, &height, 0, SOIL_LOAD_RGBA);

Either I tried with pointer
pix_scaling[p[0]];
or pointer and index
pix_scaling[*(p+0)];
both don't work. And without using pix_scaling , just
r = (*(p+0) * 0.5) + 25;
g = (*(p+1) * 0.5) + 25; 
b = (*(p+2) * 0.5) + 25; 
the image output came normally, so I guess the problem is in my lookup table function. How do I correctly do this ?
Posted
Updated 12-Apr-19 11:26am
v3

Rick is absolutly right that you arent accessing always the same pointers, but you need write code more carefully and use the debugger. Dont miss:
C++
unsigned char       * image = NULL;
unsigned char       * image1 = NULL;

For instance it isnt a good to load the image with a incomplete path. Always check for success and else write something on the console.

I also would define some struct for the color data so you can better work with. When you have such structs you can use the power of C:
C++
pData[n];//access to n-th data element
pData[n].r;//access to the r-value of the n-th data element

tip: debug with some very sample picture like a small cross or circle
 
Share this answer
 
v2
Comments
lock&_lock 12-Apr-19 11:47am    
Hi, thanks. I did check the image loader with this "if(image == NULL) exit(0);", I don't put it in my question. In my last example, I wrote that this code worked with per pixel computation inside the loop (without lookup table), so I knew image source wasn't the problem. I try to make my question not as long. As of now I use structs for header file functions. Thank you, I'll check out about debugger, I never use debugger outside IDE and this time i'm on terminal so I'm not that familiar. [UPDATE] I set pointer as NULL as you suggested, still the same issue.
Quote:
so I guess the problem is in my lookup table function. How do I correctly do this ?
I find nothing wrong with your scaling table. Of course you have to initilialize it (calling scaling) before calling makeshift.
Note you are assigning a float to an unsigned char. I believe your compiled warned you about. You actually don't need at all to use floats for the pix_scaling array.

[update]
I suppose there is something wrong in the code you didn't show.
The following program
C
#include <stdlib.h>
#include <stdio.h>
float  pix_scaling [256];
static void scaling(void)
{
  for (int i = 0; i < 256; i++)  
    pix_scaling[i] = (i * 0.5) + 25;
}

#define H 4
#define W 4

int main()
{
  unsigned char image[H*W*4];
  unsigned char image_scaled[H*W*4];

  for (int y = 0; y < H; ++y)
  {
    for (int x = 0; x < W; ++x)
    {
      for (int c = 0; c < 3; ++c)
      {
        int i = y* W * 4 + x * 4 + c;
        image[i] = (unsigned char)rand();
      }
    }
  }

  scaling();

  unsigned char *p = image;
  unsigned char *p1 = image_scaled;
  float r,g,b;

  for(int i = 0; i < H*W; i++)
  {
    r = pix_scaling[p[0]]; // here
    g = pix_scaling[p[1]];
    b = pix_scaling[p[2]];

    //to set maximum and minimum pixel value
      if   (r < 0) *(p1+0) = 0;
      else if(r > 255) *(p1+0) = 255;
      else *(p1+0) = r;

      if   (g < 0) *(p1+1) = 0;
      else if(g > 255) *(p1+1) = 255;
      else *(p1+1) = g;

      if   (b < 0) *(p1+2) = 0;
      else if(b > 255) *(p1+2) = 255;
      else *(p1+2) = b;

      p +=4;
      p1 +=4;
  }

  for (int y = 0; y < H; ++y)
  {
    for (int x = 0; x < W; ++x)
    {
      int i = y* W * 4 + x * 4 ;
      printf("(%d,%d), image { %d, %d, %d }, image_scaled {%d, %d, %d}\n", x, y, image[i], image[i+1], image[i+2], image_scaled[i], image_scaled[i+1], image_scaled[i+2]);   

    }
  }

  return 0;
}
produces:
(0,0), image { 103, 198, 105 }, image_scaled {76, 124, 77}
(1,0), image { 115, 81, 255 }, image_scaled {82, 65, 152}
(2,0), image { 74, 236, 41 }, image_scaled {62, 143, 45}
(3,0), image { 205, 186, 171 }, image_scaled {127, 118, 110}
(0,1), image { 242, 251, 227 }, image_scaled {146, 150, 138}
(1,1), image { 70, 124, 194 }, image_scaled {60, 87, 122}
(2,1), image { 84, 248, 27 }, image_scaled {67, 149, 38}
(3,1), image { 232, 231, 141 }, image_scaled {141, 140, 95}
(0,2), image { 118, 90, 46 }, image_scaled {84, 70, 48}
(1,2), image { 99, 51, 159 }, image_scaled {74, 50, 104}
(2,2), image { 201, 154, 102 }, image_scaled {125, 102, 76}
(3,2), image { 50, 13, 183 }, image_scaled {50, 31, 116}
(0,3), image { 49, 88, 163 }, image_scaled {49, 69, 106}
(1,3), image { 90, 37, 93 }, image_scaled {70, 43, 71}
(2,3), image { 5, 23, 88 }, image_scaled {27, 36, 69}
(3,3), image { 233, 94, 212 }, image_scaled {141, 72, 131}

[/update]
 
Share this answer
 
v3
Comments
Rick York 12-Apr-19 17:56pm    
I saw that too and noted it in a comment to my post above. I think that is likely to be the cause of the problem.
CPallini 12-Apr-19 18:28pm    
We had to point out such a defect (I missed your remark), but I believe it is unlikely the cause of the problem.
Rick York 12-Apr-19 20:19pm    
Really? You certainly could be right. It's hard to guess without all of the code. If I get bored this weekend I might write some code to check this out. I am rather curious to see what's going on.
lock&_lock 13-Apr-19 10:30am    
Hi, thanks. Yes, I do call scaling before makeShift. Also, I replied to Rick's comment (with my terminal screenshot). Even after trying to round or cast p[0], p[1] and p[2] the value is still zero.
CPallini 13-Apr-19 11:11am    
See my updated solution.
It appears to me the problem is here :
C++
r = pix_scaling[p[0]];
g = pix_scaling[p[1]];
b = pix_scaling[p[2]];
r, g, b will ALWAYS have the same values because p[1] is a never changed. I think you have to increment p to point to the next pixel at every iteration of the loop.
 
Share this answer
 
Comments
lock&_lock 12-Apr-19 11:29am    
Hi @Rick, thanks ! I incremented p and p1, my code was a part of even longer code and I forgot to put here. I've updated my question. It's still the same issue.
Rick York 12-Apr-19 14:53pm    
OK, I would try to do some careful debugging. You don't even need the debugger if that's a problem but it would make things easier. I would change the loop to just check the first four or five pixels. Add printfs to output the values at each step along the way: what is p[0], p[1], and p[2] to start. Then display what the values of r, g, and b are. Lastly, what are p1[0], p1[1], and p1[2] after the assignment. This should help you identify where the problem is. It appears to me that the assignments could be a problem. You have *(p1+0) = r; as an assignment statement. That is assigning a float to a UCHAR value. You might need a cast or rounding operation there to get a UCHAR from it. Regardless, printing out the values at each step will help you figure out where your problem is.
lock&_lock 13-Apr-19 10:05am    
Hi Rick, I tried to print the value to the terminal. so p[0], p[1] and p[2] look fine (here's terminal screnshot : https://i.imgur.com/08VtQQ2.png) But after the lookup table function, R, G, B are zero. Even if I round p[0], p [1] and p[2] or cast before I put into function, the result is still zero. So, you are correct this is assignment problem. I'll look for it more.
CPallini 12-Apr-19 18:29pm    
Have my 5.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900