Login
Username:

Password:

Remember me



Lost Password?

Register now!
Main Menu
Who's Online
3 user(s) are online (1 user(s) are browsing Forum)

Members: 2
Guests: 1

amiga, mordesku, more...

Browsing this Thread:   1 Anonymous Users



(1) 2 »


AROS Picture DataTypes

Joined:
5/2 17:15
From California, United States
Group:
Member
Posts: 134
Offline
A few months ago while having a discussion with Paolone and a few others about png icon tools and the needs of AROS development and it seemed that AROS PictureDataTypes would be a good place to start.

I've started a Test program called "TestPicture" that uses the Picture DataTypes along with Native Methods to make up for faulty datatypes. When I set up the test project at the beginning I decided that if I were going to devote the time and effort into TestPicture to improve picture datatypes it should have some useful purpose at the end of the test phase. So TestPicture will become an Image Viewer/Converter called "ShowPicture". More about that later, but now on to testing picture datatypes.

I have uploaded a screenshot of some test png images. I had suspected that the Ic0n chunk left over from splitting PNG icons into images was causing problems with MultiView when saving, but unknown chunks should be ignored when loading and saving PNG images. On the right side of the screenshot are some open windows displaying the png images extracted from png icons (.info). The window called "IconImage_Test.png" is a 32bit png image with the Ic0n chunk removed. It was opened in MultiView then saved as the image beside it called "IconImage_Test2.png". Notice that the resulting image has some type of masking? I opened the first test image again ("IconImage_Test.png") with my program and saved. It also resulted in an image with a mask as shown in the window called "Picture". Now comes the odd part...

My program for testing purposes was setup to automatically save the png image that is loaded. It is saved to Ram Disk: for convenience. Using my program I accidentally opened the second image from MultiView called "IconImage_Test2.png". The image looked the same with a mask when my program opened it, but the image was auto-saved to Ram Disk. Curiously I opened the resulting test image my program produced using the same datatypes as MultiView. I opened the test image in MultiView just for fun. Wow! The accidentally saved masked image became
"TestFile.png" in Ram Disk! The masked image saved correctly using my program, so I tried again to confirm.

I opened the 32bit masked image again with MultiView and saved. The resulting image is "IconImage_Test3.png". So, I have concluded that MultiView and my program which use the same PNG datatype have serious problems saving small 32bit images! When saving 24bit images everything in both programs works correctly. But what about larger png images? I tried the same test with both programs on a 500x300 png 24bit image. It opened and saved correctly. But when I tried a 32bit png things happened. Neither my test program or MultiView could save the 32bit png image correctly! But when opened again and save it worked!

Attach file:



png  AROS Picture DataTypes2.png (723.12 KB)
6991_59f2a0364831d.png 800X640 px

Posted on: 10/26 19:55
Transfer the post to other applications Transfer


Re: AROS Picture DataTypes

Joined:
5/2 17:15
From California, United States
Group:
Member
Posts: 134
Offline
As a follow up to my previous post about the odd behavior of the PNG Picture DataType when saving 32bit images with alpha I have noticed a few things of interest.

I extracted the uncompressed unfiltered pixel data from the masked image and the good image and save the data to two filed to compare. The total number of bytes is exactly the same. All the data is there, but we can't see it. Why can't we see the data? Why does opening the masked image then saving it correct the problem?

I have attached another sample image to help explain the problem with the PNG Picture DataType. These are the two png images. The one on the left is the Good Image, and the one on the right is the Masked Image. When I opened the masked image in Paint.NET I immediately noticed the transparency in the middle of the masked image that should NOT be there! In fact it should be on the outside and the mask on the outside should be inside the image! Yes, the pixel data is there, but we can't see it because the alpha has become the mask, and the mask has become the alpha. So when opening the masked image the alpha and mask are still reversed. When we save this masked image, the save process reverses the alpha and mask yet again, but this time in the correct locations! The alpha on the second pass in on the outside, and the mask is on the inside and that's why after saving the mask a second time it allows us to see the png image! Whew!!

But how do we fix the alpha-mask reversal issue? Is it a problem with the PNG DataType Save Function, or is it a problem with our implementation of PNG Library as it relates to saving PNG images? What sets the alpha and the mask in the the save process for 32bit png images?

Attach file:



png  Paint_Mask_Alpha.png (212.22 KB)
6991_59f2d66954c03.png 1410X708 px

Posted on: 10/26 23:47
Transfer the post to other applications Transfer


Re: AROS Picture DataTypes

Joined:
5/2 17:15
From California, United States
Group:
Member
Posts: 134
Offline
A temporary solution to the Alpha-Mask Reversal Problem when saving 32bit PNG images is to save the image twice! Save the first image to a temp file in Ram Disk: then read that file and save again to the real png output file so that the Alpha and Mask are correct. Delete the temp file.

I can't find anywhere in the PNG Picture DataType that would cause this problem to happen. Perhaps someone with more knowledge than I can help to pinpoint the error in the DataTypes Library or PNG Library?

The PNG Save function in the DataType definitely reverses the alpha and mask. Saving the image twice fixes it again.

Posted on: 10/27 1:25
Transfer the post to other applications Transfer


Re: AROS Picture DataTypes

Joined:
5/2 17:15
From California, United States
Group:
Member
Posts: 134
Offline
I seem to be having a one-sided conversation here!

Knowing that the PNG DataType Save Function Inverts the Alpha for 32bit images when saving I have compensated for that by writing a small function to correct the issue.

The theory is that when saving the png data alpha values of every ARGB pixel is inverted (0 becomes 255, 255 becomes 0). My function is called simply 'Invert_Alpha' and it does just that. It pre-modifies the ARGB pixel data by inverting the alpha values. When the PNG datatype then saves the image data to file it again inverts the alpha values returning them to their normal state so that we can see the image as it should be!

When we eventually find the error in the PNG DataType Save Function or more likely in the PNG Library that inverts the alpha values while saving it should be fixed. Until then enjoy this code snippet to correct the 32bit png save issue. I have also included code snippets for reading and saving png images using the PNG Picture DataType.

Mike R.

Posted on: 10/27 21:34
Transfer the post to other applications Transfer


Re: AROS Picture DataTypes

Joined:
5/2 17:15
From California, United States
Group:
Member
Posts: 134
Offline
Here is the screenshot.

Attach file:



png  Save_PNG Invert_Alpha_Screenshot.png (357.16 KB)
6991_59f40974a2cbc.png 800X640 px

Posted on: 10/27 21:37
Transfer the post to other applications Transfer


Re: AROS Picture DataTypes

Joined:
2010/8/30 7:20
Group:
Member
Posts: 947
Offline
perhaps it has to do with endianness resulting in pixel format problems? the content of that distorted image seems to be an aplha mask containging the glow effect around the icon.

Posted on: 10/28 0:58
Transfer the post to other applications Transfer


Re: AROS Picture DataTypes

Joined:
5/2 17:15
From California, United States
Group:
Member
Posts: 134
Offline
Wawa, thanks for the suggestion.

What appears to be a halo effect in this image actually isn't. You can confirm this for yourself using MultiView. Save a "normal" state pnp image extracted from an icon. It can be either image and this effect will occur if the image is 32bit. The same code in png datatype saves rgb images perfectly. Try this test. Use MultiView to open the image then select Save As to save it to a new png image. Then open the resulting masked image and save it again! The image produced by the Second save operation is correct.

This odd behavior occurs because all the alpha values are being inverted. If we pre-modify the data before saving the first time by Invert-Alpha we induce the same masked effect in our byte buffer before saving. The save process then undoes what we did and inverts it again, but this time back to its correct values so we only have to save it ONE time now instead of twice to reset alpha.

Ask yourself, why does saving one result in a masked image, but opening the masked image and saving again results in a perfectly good image using the same data? The first time it is saved the Save Png function of Png Datarype inverts alpha values. Alpha becomes mask around the edge, and the mask in the middle becomes alpha (transparent). That's incorrect. Opening the masked image doesn't alter the inverted alpha values. It displays it as it really is. But saving the masked images alters the alpha values again like a toggle switch, but this time they are correct. Interesting!

Perhaps the problem is a glitch in our implementation of Png Library that only affects 32bit images with alpha? When we use WritePixelArray and ReadPixelArray with 32bit images the pixel format is ARGB. When preparing the data using Png Library we must 'Swap the Alpha' to make ARGB into RGBA by moving the Alpha Byte in each 4byte pixel to the other side of the pixel. We use this command: "png.png_swap_alpha(png.png_ptr); Very likely this is where the problem is. The Png Library function is incorrect. Instead of just swapping the alpha pixel data from ARGB to RGBA it also Inverts each alpha byte as it goes. Every alpha 0 becomes 255, and every 255 becomes 0, and everything in between gets inverted. For example: Alpha Value = (255 - Alpha Value); that will invert the Alpha Byte.

We could comment out that line in the Save function of the Png Datatype but we would have to Swap Alpha manually on the pixel bytes making ARGB into RGBA before saving. That is certainly possible. But we don't have control of the pixel bytes at that point, Png Library does. Until we correct the error in Png Library that Inverts Alpha the only solution to counteract the masking effect is to pre-emptively Invert Alpha on the pixel data ourselves before the save function when we hand control over to Png Library which then inverts it again to its regular values which is what we wanted. Imvert Alpha is like a Toggle. Invert it once, then invert it again and we are back where we started.

That's what I did and it worked. Take a look at my last screenshot. I provided the code for Invert_Alpha. I used that function on the ARGB pixel data before saving. It pre-emptively inverted it. Then the save process reset the values to what they should be. That reduced the save operation to one iteration instead of two. The resulting png image of a single save operation can be seen in the Ram Disk called "TestImage.png". The alpha values are correct. My program and any program that Inverts Alpha on the data before saving usin Png Datatype will be able to save 32bit png images correctly. But until we correct what is causing the alpha inversion, MultiView will keep saving a masked image with all alpha values erroneously inverted. So, if you are using MultiView to save 32bit Png Images, just save the masked image, open the mask then save again and it will be correct. Try it to see what happens with 32bit png images!

Posted on: 10/28 3:11
Transfer the post to other applications Transfer


Re: AROS Picture DataTypes

Joined:
5/2 17:15
From California, United States
Group:
Member
Posts: 134
Offline
Wawa,

Sorry my explanation was a little long-winded, but I hope you get the picture?

While we are on the subject of Picture DataTypes do you or someone you know have the ability to compile AROS datatypes? I am using AmiDevCpp as my compiler but it keeps complaining about "missing symbols". I have some corrected code for the Windows Bitmap (BMP) datatype that needs to be compiled before testing. The save function was incorrect.

Thanks in advance.

Posted on: 10/28 3:17

Edited by miker on 2017/10/28 3:39:04
Transfer the post to other applications Transfer


Re: AROS Picture DataTypes

Joined:
5/2 17:15
From California, United States
Group:
Member
Posts: 134
Offline
Wawa,

This is something I found in the Png Library in the AROS source:

pngwtran.c

#ifdef PNG_WRITE_SWAP_ALPHA_SUPPORTED
if ((png_ptr->transformations & PNG_SWAP_ALPHA) != 0)
png_do_write_swap_alpha(row_info, png_ptr->row_buf + 1);
#endif

#ifdef PNG_WRITE_INVERT_ALPHA_SUPPORTED
if ((png_ptr->transformations & PNG_INVERT_ALPHA) != 0)
png_do_write_invert_alpha(row_info, png_ptr->row_buf + 1);
#endif

*******************************************************

The two function are right next to each other. Something in the Save PNG process for the PNG DataType is inverting our alpha values.

*******************************************************

This is the function Invert Alpha in pngwtran.c
Notice that it is basically the same format that I used to reverse the process: Alpha = (255 - Alpha);

*******************************************************


if (row_info->bit_depth == 8)
{
/* This inverts the alpha channel in RGBA */
png_bytep sp, dp;
png_uint_32 i;
png_uint_32 row_width = row_info->width;

for (i = 0, sp = dp = row; i < row_width; i++)
{
/* Does nothing
*(dp++) = *(sp++);
*(dp++) = *(sp++);
*(dp++) = *(sp++);
*/
sp+=3; dp = sp;
*dp = (png_byte)(255 - *(sp++));
}
}


Posted on: 10/28 4:25
Transfer the post to other applications Transfer


Re: AROS Picture DataTypes

Joined:
5/2 17:15
From California, United States
Group:
Member
Posts: 134
Offline
I have searched through the Png Library sources and I didn't immediately find any reason why it would arbitrarily invert the alpha values in the pixel data. However, there may be another culprit in this 32bit Png alpha inversion mystery...

This is the save function being used:

/**************************************************************************************************/

BOOL savepic_by_datatype_alpha(RGBImage *pic, char *file_name, char *type)
{
Object *DTImage = NULL;
struct BitMapHeader *bmhd;
struct dtWrite dtw;
struct pdtBlitPixelArray dtb;
FILE *file = NULL;
BOOL retval = FALSE;
type = "png";

printf("\nSave Picture by DataType ('%s')!\n\n", type);

DTImage = NewDTObject( (APTR)NULL,
DTA_SourceType, DTST_RAM,
DTA_BaseName, (IPTR)type,
PDTA_DestMode, PMODE_V43,
TAG_DONE);
if (!DTImage) return(FALSE);


if (GetDTAttrs(DTImage,PDTA_BitMapHeader,(IPTR)&bmhd,TAG_DONE))
{
dtb.MethodID = PDTM_WRITEPIXELARRAY;
dtb.pbpa_PixelData = pic->Data;
dtb.pbpa_PixelFormat = PBPAFMT_ARGB;
dtb.pbpa_PixelArrayMod = pic->Width*4;
dtb.pbpa_Left = 0;
dtb.pbpa_Top = 0;
dtb.pbpa_Width = pic->Width;
dtb.pbpa_Height = pic->Height;

bmhd->bmh_Width = pic->Width;
bmhd->bmh_Height = pic->Height;
bmhd->bmh_Depth = 32;
bmhd->bmh_PageWidth = 320;
bmhd->bmh_PageHeight = 240;

DoMethodA(DTImage, (Msg) &dtb);

//write datatype object to file
if (file = Open (file_name,MODE_NEWFILE))
{
dtw.MethodID = DTM_WRITE;
dtw.dtw_GInfo = NULL;
dtw.dtw_FileHandle = file;
dtw.dtw_Mode = DTWM_RAW;
dtw.dtw_AttrList = NULL;

if (DoMethodA(DTImage, (Msg) &dtw)) retval = TRUE;
}
}

if (file) Close (file);
if (DTImage) DisposeDTObject(DTImage);
return retval;
}

/**************************************************************************************************/

Next step is to verify if MultiView uses PDTM_WRITEPIXELARRAY when saving 32bit Png images since it produces the same mysteriously masked images! If it does then some more research may point to the real alpha inversion suspect, the one who is perpetrating this sinister act of hidden pixels. Who doesn't like a good Detective Mystery?

Posted on: 10/28 14:31
Transfer the post to other applications Transfer



(1) 2 »



You can view topic.
You cannot start a new topic.
You cannot reply to posts.
You cannot edit your posts.
You cannot delete your posts.
You cannot add new polls.
You cannot vote in polls.
You cannot attach files to posts.
You cannot post without approval.

[Advanced Search]


Search
Top Posters
1 paolone
paolone
4359
2 magorium
magorium
4095
3 phoenixkonsole
phoenixkonsole
3892
4 nikolaos
nikolaos
3693
5 deadwood
deadwood
2923
6 ncafferkey
ncafferkey
2646
7 mazze
mazze
2214
8 clusteruk
clusteruk
2109
9 Kalamatee
Kalamatee
2024
10 damocles
damocles
1789
© 2004-2017 AROS Exec