This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

fbdev: why is this necessary?

Using the ARBG888 format, I need to use the following bit of code to get the pixels into the frame buffer memory:

  pmem = addr;
  for(i=0;i<N;i++){
    offset=0;
    for(j=0;j<M;j++){
      a4bpix.byte[0] = 0x00;
      a4bpix.byte[1] = ibuf[i][j];
      a4bpix.byte[2] = ibuf[i][j];
      a4bpix.byte[3] = ibuf[i][j];
      memcpy(pmem+offset, a4bpix.byte, 4);
      offset+=4;
    }
    pmem+=((M*32)>>3);
  }

question: Why do I need to multiply by 32 and shift right by 3 bits, multiply by 4 all together) the pointer after each line?  If I do not do this I get a segmentation fault.  What is going on in the hardware that makes the pointer adjustment necessary?

 

Lee Holeva

 

  • Holeva,

    I assume that pmem is a u8 type pointer.

    for every N you need adjust pmem to move the next line. that is right procedure. you can do pmem += M*4;

    if you do not change pmem for every i(N), you just copy the different data to the first line again and again, but I did not see how you can get a segmentation fault.

    In order to assit you, please provide your full souce codes

  • Actually, I do not get  a segmentation fault using the above code.  If I simply increment pmem by M, the number of bytes per line, I see four liitle copies of the image displayed.  If on the other hand, I increment pmem by M*32, I get a segmentation fault.  My question is why is the multiplcation of the increment of pmem by 4 required?  What is going on in the hardware that makes this necessay?

  • Lee,

    You certainly don't want to increment pmem by M*32 since this will cause a buffer over flow. You should increment by M*4 (which is what your example code does) since there are 4 bytes per pixel. If you try to access non word aligned addresses then you might also get an error.

    How big are M & N?

    At what point to you get the seg fault? (i.e. can you print M & N during the run to see if it is possibly a buffer over run?)

    I would update pmem inside the inner loop by adding 4 every loop rather than updating offset unless you plan on doing some line based optimizations later.

    BR,

    Steve

  • M=480 N=720

    pmem is a pointer to unsigned char and ibuf is a 2D array of unsigned char.  Incrementing pmem by 4 while writing each line makes sense, but the need to multiply pmem by 4 at the end of each line is mysterious.  It looks like write a line of pixels to the framebuffer and then skip three lines before writing the next line.  What is going on in the video back-end hardware that requires this?  A possible clue is that if I do not skip three lines I get not a single image, but four duplicate little images.

     

    Lee Holeva

     

  • Four bytes are moved each loop of M. Makes sense to increment pmem by M*4 bytes after M loops as pmem is NOT incremented in the M loop itself. The multiply and shift seem a bit redundant. Shifting left by 5 and then right by 3 is the same as shifting left by 2. Unless shifting left by 5 will move significant bits off the end. I would suspect most compilers would just optimize that out to a single shift. Implied in your code fragment is a grayscale to RGB888 conversion where each pixel is big endian and padded to 32 bits. Something like this.

    #define N 720
    #define M 480
    void grayscale_to_aligned_rgb888
    ( const unsigned char grayscale[N][M],
      unsigned char rgb888[N*M*4]
    )
    {
      register unsigned char       *pdst = rgb888;
      register const unsigned char *psrc = grayscale;
      register unsigned char        v;
      for(i=0;i<N;i++)
      {
        for(j=0;j<M;j++)
        {  v      = *psrc++;
          *pdst++ = 0x00; /* Pad, MSB*/
          *pdst++ = v;    /* Red */
          *pdst++ = v;    /* Green */
          *pdst++ = v;    /* Blue, LSB */
        }
      }
    }
    Is your intent something else entirely?