AROS Picture DataTypes

miker1264 · 19965

Yannick

  • Newbie
  • *
    • Posts: 37
    • Karma: +4/-0
Reply #45 on: September 17, 2019, 08:09:25 AM
One thing that's sometimes causes troubles with the alpha channel : it might need to be inverted.
Internally this codes opacity, not transparency, i.e. 255 is fully opaque and 0 is fully transparent.


miker1264

  • Legendary Member
  • *****
    • Posts: 1827
    • Karma: +84/-6
Reply #46 on: September 17, 2019, 10:22:49 AM
One thing that's sometimes causes troubles with the alpha channel : it might need to be inverted.
Internally this codes opacity, not transparency, i.e. 255 is fully opaque and 0 is fully transparent.

That's true. Thanks for the information.

I saved the uncompressed chunky pixel data from the original 32bit png as a .bin file. When I have time I will use a hex editior to compare the scan0 at the end of the bmpx file and compare it directly to the first scanline in the png which is 'ARGB'. I can compare byte by byte to see what format the bmpx 32bit data is in the actual bmpx file.

That also gives me a good test case to use the new Zune Hex Editor. Thank you for that.



miker1264

  • Legendary Member
  • *****
    • Posts: 1827
    • Karma: +84/-6
Reply #47 on: September 18, 2019, 12:38:56 AM
The problem with the Padding Bytes at the end of the scanlines has been resolved.
It was a Mathematical Error on my part. The image on the bottom right is missing
Padding Bytes before I made the correction. The image at the top left has padding.

The formula for testing if a scanline is Modulus 4 (ends evenly on a 4-byte boundary)
is as follows:

//** Test for Modulus & Set Padding Values. **//
   
   LONG pixelElements = ( depth / 8 );
   //Is it Modulus 4??
   if((width * pixelElements)%4 == 0)
   {
      alignwidth = (width * pixelElements); //bytesPerPixel
      alignbytes = width;
   }
   else
   {
      alignwidth = ((width * pixelElements) + 3) & ~3UL; //Not Modulus 4
      alignbytes = (alignwidth / pixelElements);
   }

    >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
   
    if( FWrite( filehandle, linebuf, (alignbytes * pixelElements), 1 ) != 1 )


I was using  (alignbytes * pixelElements) as if it were equivalent to: alignwidth!
Mathematically that is incorect because...

If your image dimensions are 299x144 & it is 24bit RGB
299*3=897 so it requires 3 padding bytes such that alignwidth = 900.
Is it evenly divisible by 4? 900/4=225. alignbytes = (alignwidth/3) = 300.
That works.

Next image dimensions are 474x329 & it is 24bit RGB
474*3=1422 so it requires 2 padding bytes such that alignwidth = 1424.
Is it evenly divisible by 4? 1424/4=356. alignbytes = (alignwidth/3) = 474.6667
As far as I know, an int of that will yield 474 which is where we started.
That doesn't work!

Notice the FWrite statement:
 if( FWrite( filehandle, linebuf, (alignbytes * pixelElements), 1 ) != 1 )

The simple solution is to only use alignwidth but not (alignbytes * pixelElements)
because we have proven that the two are not equivalent.

 if( FWrite( filehandle, linebuf, alignwidth, 1 ) != 1 ) //That works!



miker1264

  • Legendary Member
  • *****
    • Posts: 1827
    • Karma: +84/-6
Reply #48 on: September 18, 2019, 12:52:56 AM
Using the Nice Zune Hex Editor and my faithful HxD Hex Editor (which is very powerful)
I am very close to a solution for Displaying 32bit BMPX with Alpha Transparency.

Here are my test results for the same group of pixels in three samples.
My conclusions are that the PNG pixel data is 'ARGB' so it displays as transparent.
The Originl BMPX File is 'BGRA' But after Load_BMPX when it reaches my display
function it is transformed into 'XRGB' where 'X' if FF (255) so it is not transparent.
Now I have to find out where the missing Alpha Values went. Where are they hiding?

Note: I start reading pixel data at '1C' on the top line.

Test_PNG
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 1C 7E 63 0B 93 D9 A5 19 F2 DE A2 1D FF DE A2 1E FF EA C4 70 FF F9 EE D7 FF FE FC F7 FF FD FA F4 FF FD FA F4 FF FD FA F4 FF FD FA F4 FF FD FA F4 FF FD FA F4 FF FD FA F4 FF FD FA F4 FF FD FA F4 FF FD FA F4 FF FD FA F4 FF FD FA F4 FF FD FA F4 FF FD FA F4 FF FD FA F4 FF FD FA F4 FF FD FA F4 FF FD FA F4 FF FD FA F4 FF FD FA F4 FF FD FA F4 FF FD FA F4 FF FE FB F6 FF FB F2 E0 FF E8 C0 63 FF DE A3 1D FF DE A2 1D FF DE A2 1D FF DE A2 1D FF DE A2 1D FB DD A0 1C C0 DA 9D 1B 3D 9F 73 13 00 49 49 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

Gold_Crown_Export
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 19 A5 D9 93 1D A2 DE F2 1E A2 DE FF 70 C4 EA FF D7 EE F9 FF F7 FC FE FF F4 FA FD FF F4 FA FD FF F4 FA FD FF F4 FA FD FF F4 FA FD FF F4 FA FD FF F4 FA FD FF F4 FA FD FF F4 FA FD FF F4 FA FD FF F4 FA FD FF F4 FA FD FF F4 FA FD FF F4 FA FD FF F4 FA FD FF F4 FA FD FF F4 FA FD FF F4 FA FD FF F4 FA FD FF F4 FA FD FF F4 FA FD FF F4 FA FD FF F6 FB FE FF E0 F2 FB FF 63 C0 E8 FF 1D A3 DE FF 1D A2 DE FF 1D A2 DE FF 1D A2 DE FF 1D A2 DE FF 1C A0 DD FB 1B 9D DA C0 13 73 9F 3D 00 49 49 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

1C 7E 63 0B   'ARGB'  - - Test_PNG.bin
0B 63 7E 1C  'BGRA'  - -  Gold_Crown_Export.bmpx
FF 7E 63 0B   FF D9 A5 19   'XRGB' Test_BMPX.bin



asymetrix

  • Newbie
  • *
    • Posts: 6
    • Karma: +0/-0
Reply #49 on: September 18, 2019, 11:27:32 AM

The formula for testing if a scanline is Modulus 4 (ends evenly on a 4-byte boundary)
is as follows: ...


Don't know if it helps, from Kochans Programming in C book :

For example, to round off 256 days to the next largest number of days evenly
divisible by a week, values of i = 256 and j = 7 can be substituted into the
above formula as follows.
Next_multiple = 256 + 7 - 256 % 7 = 256 + 7-4
= 259



miker1264

  • Legendary Member
  • *****
    • Posts: 1827
    • Karma: +84/-6
Reply #50 on: September 18, 2019, 12:13:31 PM

The formula for testing if a scanline is Modulus 4 (ends evenly on a 4-byte boundary)
is as follows: ...


Don't know if it helps, from Kochans Programming in C book :

For example, to round off 256 days to the next largest number of days evenly
divisible by a week, values of i = 256 and j = 7 can be substituted into the
above formula as follows.
Next_multiple = 256 + 7 - 256 % 7 = 256 + 7-4
= 259

That works.

One main problem, which has been solved, was that according to the bmp specs the scanline length must be evenly divisble by 4.

A potential problem also exists in the Load BMP function that is from the old BMP datatype. It assumes (alignbytes * 4) = alignwidth. But that's not true in all cases.

I'll have to examine Load BMP to make sure everything is correct to support Load 32bit.



miker1264

  • Legendary Member
  • *****
    • Posts: 1827
    • Karma: +84/-6
Reply #51 on: September 18, 2019, 10:53:28 PM
Displaying Transparent BMPX Files!

Yes. It is possible.

I will have to re-write parts of Load_BMP in the BMPX Datatype for 32bit BMPX with Alpha.



salvatore

  • Guest
Reply #52 on: September 18, 2019, 11:18:18 PM
well miker :D



miker1264

  • Legendary Member
  • *****
    • Posts: 1827
    • Karma: +84/-6
Reply #53 on: September 18, 2019, 11:43:26 PM
That means that Alpha Transparency may also be possible using an ILBM Deep Image with 32 bitplanes. That would be an exciting moment. 😊



mmartinka

  • Newbie
  • *
    • Posts: 48
    • Karma: +4/-0
Reply #54 on: September 19, 2019, 02:25:10 AM
very good job  8)



aha

  • Junior Member
  • **
    • Posts: 66
    • Karma: +41/-0
Reply #55 on: September 19, 2019, 10:31:28 AM
Simply great!  :) I am looking forward to it.



miker1264

  • Legendary Member
  • *****
    • Posts: 1827
    • Karma: +84/-6
Reply #56 on: September 20, 2019, 08:04:00 AM
In the past few days I have tested displaying BMPX files with Alpha Mask. In the process I've discovered a few things.

After several attempts to display transparent bmpx images I suspected there might be something wrong in the way
that the datatypes library handles reading from the picture datatype as 'RGBA' but it has no problem with 'ARGB' such
as with png datatype. Transparent png images using 'ARGB' display perfectly. So I came up with a "Direct Read"
function to read the data in the bmpx file directly then display it on screen. That method worked perfectly as well.

I found these few lines in the PNG picture datatype which seems to confirm my belief there's something wrong here!

case PNG_COLOR_TYPE_RGB_ALPHA:
       png.png_depth = 32;
   #if 0
       png.png_format = PBPAFMT_RGBA;
   #else
       /* FIXME: PBPAFMT_RGBA not supported by picture.datatype, therefore using PBPAFMT_ARGB */
       png.png_format = PBPAFMT_ARGB;
       png_set_swap_alpha(png.png_ptr);
   #endif


So I proved that "Direct Read" works. It's interesting that I use 'RGBA' to encode the bmpx file but
Writing to the datatype (WRITEPIXELARRAY) works fine as well. After Save_BMPX programs such as
PixelFormer, GIMP and maybe Photoshop CS4/5 display the file as Transparent BMPX.

For example, when reading from the datatype as 'ARGB' all the Alpha values are changed to 'FF' (255).
When I change to reading from the datatype as 'RGBA' (wherein lies the problem) and using 'ARGB' to
display the image I get a skewed blue-ish but transparent image! In this case Read 'RGBA' - Display 'ARGB'
distorts the Blue values transforming them into, you guessed it 'FF' (255). Using 'RGBA' it can't read the
fourth value, either Alpha or Blue, whichever is indicated. I hope that all makes sense.

This is my Direct Read Method that works well for my graphics program:

if(picType == "bmp")
       {
            BPTR fileHandle = Open(fname, MODE_OLDFILE); //MODE_OLDFILE
           Seek(fileHandle,54,OFFSET_BEGINNING);
           Read(fileHandle,bitmapImage,(in_pic->Width*4*in_pic->Height)); //BGRA
           UBYTE tempRGB;
           int imageIdx = 0;
            for (imageIdx = 0;imageIdx < (in_pic->Width*4*in_pic->Height);imageIdx+=4)
            {
                tempRGB = bitmapImage[imageIdx]; //blue
            bitmapImage[imageIdx] = bitmapImage[imageIdx + 3]; //alpha
            bitmapImage[imageIdx + 3] = tempRGB; //blue

            tempRGB = bitmapImage[imageIdx+1]; //green
            bitmapImage[imageIdx+1] = bitmapImage[imageIdx + 2]; //red
            bitmapImage[imageIdx + 2] = tempRGB; //green
            }
            Flip_Vertical(bitmapImage, in_pic->Width, in_pic->Height, 4);
            Close(fileHandle);
        }
       
        showImage(bitmapImage, bitmapInfoHeader, fname, isIcon);



So, in the next few days I will fix up what I have for the BMPX picture datatype.
It Loads and Saves BMP files correctly but it currently can't load an alpha mask.

Maybe I can fix the problem with alpha transparency in a future update along with support for OS/2 bitmaps. :-)
« Last Edit: September 20, 2019, 08:17:25 AM by miker1264 »



miker1264

  • Legendary Member
  • *****
    • Posts: 1827
    • Karma: +84/-6
Reply #57 on: September 20, 2019, 09:32:31 AM
Sorry folks!

To summarize all the technical stuff -

For all the programmers out there, when trying to display 32bit bmpx files with alpha transparency there's a potential problem with datatypes library. When reading as 'ARGB' such as with 'PNG' it works. But it doesn't work reading with 'RGBA' and that is what bmpx requires to display transparecy!

Until the problem is fixed you should use a direct read method to get the pixel data directly from the bmpx file. All the data is there incuding the alpha values.

The bmpx picture datatype is finished and will be released as early as tomorrow.



salvatore

  • Guest
Reply #58 on: September 20, 2019, 10:58:52 AM
but you're basically fixing the datatypes and also creating new :-\



miker1264

  • Legendary Member
  • *****
    • Posts: 1827
    • Karma: +84/-6
Reply #59 on: September 20, 2019, 11:56:01 AM
but you're basically fixing the datatypes and also creating new :-\

The short answer is YES.

As far as Picture Datatypes I'm fixing what needs fixing and adding Save Functions where needed with a special emphasis at first on fixing up BMP datatype and ILBM datatype as I was directed to do about a year ago.

As for JPEG, TARGA, PCX datatypes out of respect for other developers I would ask the original authors if they intend to fix them or if I may be permitted to do so.

As far as problems with Datatypes Library like the one I found reading 'RGBA' when I have time I have a good chance of finding the problem now that I have witnessed its effect.

Because everything takes time and I have spent over 40 hours on BMPX datatype alone I am going to release it as it is tomorrow then go back when I have free time to try to find the problem in the libraries to fix transparency using 'RGBA'.  😊

Tomorrow I'll start fixing ILBM datatype to add Save ILBM functions. That will be fun!

That's the LONG ANSWER.