bitblt code

TAHAIC
2011-04-28
2013-04-29
  • TAHAIC

    TAHAIC - 2011-04-28

    I am trying to work out how the code in bitblt works but I am a little puzzeled over why all parameters in the declaration are of type char. There seems to be something going on here that I am not following. I can sort of understand the logic but I don't understand how the char type is being used here - they seemed to be being used as numbers which in my brain is a type mismatch and I just don't get it.

    for example:

    void bitblt(char x, char y, char width, char height, char mode, char* data)
    {
           unsigned char row, column, shift, shift2, mask1, mask2, n, n2, temp, RX_temp;
           int offset, offset2;
    .
    .
    .
           offset=0;   //start at the beginning of data
           offset2=-width; //offset2 points a the previous row

       for(row = 0;row < n;row++)         //loop through all rows
       {
        //if NULL was passed for data, take it from the serial port.
        //it is necessary to have 2 rows of data, current and previous to do bitblt
        //since 0<width<128 (display is only 128 wide), we can use the second 128 bytes in buffer to hold the previous row

        read_block(x,(row+(y/8)),width,buffer);     //read the row in(background image data)

    "row" is of Type "unsigned char" but is being treated as an interger!???  -   for(row = 0;row < n;row++)

    I am runnig through a senario of x =0, y=22, hieght = 20, width = 80, mode = 4 and data=0xFF to invert all pixels in the box. In this senario "offset2=-width" makes offset2 = -80!!!??? There is something wrong with my logic here!
    On the first pass "row+(y/8)" would equal 0+(22/8) = 2.75 which again is clearly wrong.

    Can you please help me out in trying to understand what going on here.

    Thanks 

     
  • Jennifer Holt

    Jennifer Holt - 2011-04-28

    It has been quite a while since I looked at that code, and I remember writing it was a serious pain, so don't feel too bad about it being kind of opaque;)  For why I used chars, I wanted an 8-bit data type, and I'm not used to using uint8_t or int8_t. If you included stdint.h you could use the exact-width integer types.  Either way, C is perfectly happy using chars as integers, after all, they are just 8-bit numbers to the processor.

    offset2 is an index to the array "data" passed to the bitblt function. The array "data" holds image data in sequential rows. So if X is an index that points to the start of a row, X-width points to the start of the previous row. The bitblt function needs to know about the current row and the previous one because sometimes the rows in the image data don't line up with the rows on the display, and the function has to calculate the byte to send to the LCD from part of the current row, and part of the previous one.  Since offset2 starts at -width, and both offset and offset2 are incremented together, offset2 always points to the byte directly "above" the one pointed to by offset. On the first row, there is no preceding row, and the negative array index is meaningless. In C, an array index is just a number added to the base pointer of the array, if the index is negative, you will get values outside the memory range of the array. If you are writing to that location, this would be very bad, as you can change things you don't intend to. If you just read the values, you get meaningless stuff. This bogus data is all right since the first row is treated special and any bits from the previous row are masked off when it is written to the display.

    In the case of the data for bitblt coming from the serial port, there is a line of code that saves each incoming byte in the upper half of buffer, so it can be used as the previous row.

    for the calculation of 
    read_block(x,(row+(y/8)),width,buffer); //read the row in(background image data)
    y is char(integer) value, and so is the constant 8. When you divide two integers, the result is an integer and equal to the integer part of the true value. so in your example, 0+(22/8) = 2. This works since pixel 22 is in the third row(pixels 0-7 are the first row, 8-15 the second, and 22 is the 7th pixel in row 3). The rows start counting from 0, so 2 is the third row. This line of code reads in what was already on the display, since writing to row 3 will overwrite pixels with y-values from 16 to 23, and you only want to change pixels from 22 onward. This allows the function to write back the correct values for what you don't want to change.

     
  • TAHAIC

    TAHAIC - 2011-05-01

    Thats an excellent explanation thank you. I am starting to get it now.

    There is still one thing I don't understand - when reading data from ram

                                   if (data!=NULL) //decide if data comes from ram or serial
    temp = ( (data << shift) | (data >> shift2) ); //data from ram
           else

    The first time round offset++ = 1, so doesn't this ignore the first byte of data (i.e. instead of starting at offset = 0) and put all subsequent data out of line by one byte?
       

     
  • Jennifer Holt

    Jennifer Holt - 2011-05-02

    The ++ and - operators depend on where you put them. If they are located after the variable ie offset++, then they are incremented after the value in the variable is used, if you put them in front, ie ++offset, they are incremented before the value is used. So on the first iteration of the loop, the value in offset is 0 for purposes of indexing the array, but gets incremented to 1 after that statement is executed.

     
  • TAHAIC

    TAHAIC - 2011-05-02

    Awesome, thank you.

     

Get latest updates about Open Source Projects, Conferences and News.

Sign up for the SourceForge newsletter:





No, thanks