Re: BUG: CAIRO_FORMAT_ARGB32, image_surface transparency = CAIRO_IMAGE_IS_OPAQUE after write_png()

[email protected]
Newsgroups gmane.comp.lib.cairo
Message-ID <[email protected]>
Tuesday, June 7, 2016, 8:58:57 AM, you wrote:

lmr> Tuesday, June 7, 2016, 1:49:47 AM, you wrote:

AJ>> On 07/06/16 05:37, chnav wrote:
>>> Hi,
>>> 
>>> have discovered sporatic bug working with transparent images,
>>> which I finally managed to reproduce.
>>> 
>>> ------- code 1 begin --------------
>>> cairo_surface_t *surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 256, 256);
>>> cairo_t *cr = cairo_create (surface);
>>> // Initialisation
>>> cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
>>> cairo_set_source_rgba(cr, 1.0, 1.0, 1.0, 1.0);
>>> cairo_paint(cr);
>>> cairo_surface_write_to_png(surface, "cairo_test3a.png");
>>> // ...
>>> cairo_set_source_rgba(cr, 1.0, 1.0, 1.0, 0.5);
>>> cairo_paint(cr);
>>> cairo_surface_write_to_png(surface, "cairo_test3b.png");
>>> ------- code 1 end --------------
>>> 
>>> Both files supposed to be 32 bit PNG with alpha but above will produce
>>> 24 bit png without alpha. 
>>> 
>>> 
>>> ------- code 2 begin --------------
>>> cairo_surface_t *surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 256, 256);
>>> cairo_t *cr = cairo_create (surface);
>>> // Initialisation
>>> cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
>>> cairo_set_source_rgba(cr, 1.0, 1.0, 1.0, 0.9);
>>> cairo_paint(cr);
>>> cairo_surface_write_to_png(surface, "cairo_test3a.png");
>>> // ...
>>> cairo_set_source_rgba(cr, 1.0, 1.0, 1.0, 0.5);
>>> cairo_paint(cr);
>>> cairo_surface_write_to_png(surface, "cairo_test3b.png");
>>> ------- code 2 end --------------
>>> 
>>> Now both files are 32 bit PNG alpha.
>>> 
>>> 
>>> Short explanation, tracing "code 1" in debugger:
>>> 
>>> 1. Before 1st call of write_png():
>>>    image->transparency = CAIRO_IMAGE_UNKNOWN;
>>> 2. cairo_surface_write_to_png() calls _cairo_image_analyze_transparency();
>>> 3. _cairo_image_analyze_transparency() see CAIRO_IMAGE_UNKNOWN and
>>>    scans every pixels' alpha. It founds all of them equal 255 and changes
>>>    image->transparency = CAIRO_IMAGE_IS_OPAQUE (!!!)

AJ>> If all alpha is 255 the image is opaque.


>>> 4. From now on any subsequent call of _cairo_image_analyze_transparency()
>>>    will return CAIRO_IMAGE_IS_OPAQUE;
>>> 5. cairo_surface_write_to_png() sets png_color_type = PNG_COLOR_TYPE_RGB;
>>> 
>>> 
>>> I assume if we create image surface CAIRO_FORMAT_ARGB32 then
>>> image->transparency must be CAIRO_IMAGE_HAS_ALPHA

AJ>> That assumption is incorrect. Cairo analyses image transparency to
AJ>> ensure it uses the most efficient format when writing out images to PNG,
AJ>> PDF, and PS.

lmr> Ok, but writing PNG shall not affect consequent writings. If we paint
lmr> later with transparent source it is not opaque anymore and then 
lmr> _cairo_image_analyze_transparency() shall run again.

lmr> Either we have optimised PNG which requires time cost analyzing,
lmr> or we have intentionally set CAIRO_FORMAT_ARGB32 and write
lmr> non-optimized 32-bit PNG.

lmr> I think it would be good idea to add some function like
lmr> cairo_surface_write_to_png_flat() which will dump image data
lmr> to PNG in the same format as surface. It also can be usefull for
lmr> debugging then user can open file in image viwer and see what data
lmr> in what format hi is actually working on.


lmr> I am making slippy web map and generating overlay images. Tiles can be
lmr> opaque or transparent depends on data and I cannot know which will go
lmr> first.

I have added my usecase

------- code 3 begin --------------
        cairo_surface_t *surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 256, 256);
        cairo_t *cr = cairo_create(surface);
        while(havedata) {
                // clear canvas
                cairo_set_operator(cr, CAIRO_OPERATOR_CLEAR);
                cairo_paint(cr);
                cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
                // do real data drawing
                _PaintSomeData(cr);
                cairo_surface_write_to_png_stream(surface, ..........);
        }
------- code 3 end --------------


lmr> Right now the tile surface cannot be re-used.

lmr> Thanks and Regards
lmr> chnav

lmr> Tuesday, June 7, 2016, 8:01:52 AM LOCAL
lmr> --


>>> 
>>> 
>>> Thanks and Regards
>>> chnav
>>> 
>>> 
>>> Monday, June 6, 2016, 9:52:54 PM LOCAL
>>> 




-- 
cairo mailing list
[email protected]
https://lists.cairographics.org/mailman/listinfo/cairo
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.