Bug 90680

Summary: Problem with using surface RGB16_565 as source
Product: cairo Reporter: Ondřej Tůma <ondrej.tuma>
Component: image backendAssignee: Chris Wilson <chris>
Status: RESOLVED MOVED QA Contact: cairo-bugs mailing list <cairo-bugs>
Severity: normal    
Priority: medium    
Version: 1.12.2   
Hardware: x86-64 (AMD64)   
OS: Linux (All)   
Whiteboard:
i915 platform: i915 features:
Attachments: Error output image

Description Ondřej Tůma 2015-05-27 14:06:42 UTC
Created attachment 116078 [details]
Error output image

Hi,

I'm using version on debian Wheezy (1.12.2) or debian Jessie (1.14.0). Problem "works" on both version. As i use cairomm or vala, this problem is in cairo (vala doing precompilation source to C source).

I'm working with two image surfaces with format RGB16_565. One as source, and one as target. Sometimes using surface work fine, sometimes cairo gets another part of surface memmory, so get's another source part which I want.

Here is test in Vala language:
// start of Vala test
// modules: Cairo

const uint16 WIDTH = 720;
const uint16 HEIGHT = 360;

public Cairo.ImageSurface get_source () {
    Cairo.ImageSurface surface = new Cairo.ImageSurface (
                Cairo.Format.RGB16_565,
                WIDTH,
                HEIGHT);

    Cairo.Context cr = new Cairo.Context (surface);
    cr.set_antialias (Cairo.Antialias.NONE);
    cr.set_line_width (1.0);

    cr.rectangle (0, 0, WIDTH, HEIGHT);
    cr.set_source_rgb(0.5, 0.5, 0.5);
    cr.fill();

   for (uint16 y = 0; y < HEIGHT; y+=5) {
        cr.set_source_rgb (0.0, 0.0, y/(double)HEIGHT);
        cr.move_to(0, y);
        cr.line_to(WIDTH, y);
        cr.stroke();
    }

    for (uint16 x = 0; x < WIDTH; x+=10) {
        cr.set_source_rgb (0.0, x/(double)WIDTH, 0.0);
        cr.move_to (x, 0);
        cr.line_to (x, HEIGHT);
        cr.stroke();
    }

    surface.write_to_png ("source.png");
    return surface;
}

public void use_source (Cairo.ImageSurface source) {
    Cairo.ImageSurface surface = new Cairo.ImageSurface (
                Cairo.Format.RGB16_565,
                162,
                115);

    Cairo.Context cr = new Cairo.Context (surface);
    cr.set_antialias (Cairo.Antialias.NONE);
    cr.set_line_width (1.0);
    cr.set_source_surface (source, -166, -139);

    cr.arc(80, 60, 30, 0, 6.28);    // bad part
    cr.fill();

    cr.rectangle(0,0,162,30);       // right part
    cr.fill();

    surface.write_to_png ("target.png");
}

public int main (string [] args) {
    Cairo.ImageSurface source = get_source();
    use_source (source);

    return 0;
} // end of vala test

To compile, type:
 ~$ valac --pkg=cairo cairo-bug.vala

And Here is c++ test:

// Start of c++ test
#include <stdint.h>

#include <cairomm/surface.h>
#include <cairomm/context.h>

const uint16_t WIDTH = 720;
const uint16_t HEIGHT = 360;

Cairo::RefPtr<Cairo::ImageSurface> get_source () {
    Cairo::RefPtr<Cairo::ImageSurface> surface = Cairo::ImageSurface::create(
                Cairo::FORMAT_RGB16_565,
                WIDTH,
                HEIGHT);

    Cairo::RefPtr<Cairo::Context> cr = Cairo::Context::create(surface);
    cr->set_line_width(1.0);
    cr->set_antialias (Cairo::Antialias::ANTIALIAS_NONE);

    cr->rectangle (0, 0, WIDTH, HEIGHT);
    cr->set_source_rgb(0.5, 0.5, 0.5);
    cr->fill();

    for (uint16_t y = 0; y < HEIGHT; y+=5) {
        cr->set_source_rgb (0.0, 0.0, y/(double)HEIGHT);
        cr->move_to(0, y);
        cr->line_to(WIDTH, y);
        cr->stroke();
    }

    for (uint16_t x = 0; x < WIDTH; x+=10) {
        cr->set_source_rgb (0.0, x/(double)WIDTH, 0.0);
        cr->move_to (x, 0);
        cr->line_to (x, HEIGHT);
        cr->stroke();
    }

    surface->write_to_png ("source.png");
    return surface;
}

void use_source (Cairo::RefPtr<Cairo::ImageSurface> source) {
     Cairo::RefPtr<Cairo::ImageSurface> surface = Cairo::ImageSurface::create(
                Cairo::FORMAT_RGB16_565,
                162,
                115);

    Cairo::RefPtr<Cairo::Context> cr = Cairo::Context::create(surface);
    cr->set_line_width(1.0);
    cr->set_antialias (Cairo::Antialias::ANTIALIAS_NONE);
    cr->set_source (source, -166, -139);

    cr->arc(80, 60, 30, 0, 6.28);   // bad part
    cr->fill();

    cr->rectangle(0,0,162,30);      // right part
    cr->fill();

    surface->write_to_png ("target.png");
}

int main (int argv, char ** argc) {
    Cairo::RefPtr<Cairo::ImageSurface> source = get_source();
    use_source (source);

    return 0;
} // End of c++ test


To compile cairomm test, type:
 ~$ g++ `pkg-config --libs --cflags cairomm-1.0` -std=c++11 cairo-bug.cc -o cairo-bug

In attachment image you can see what fails. If I use RGB24 format, all works fine :)
Comment 1 GitLab Migration User 2018-08-25 13:29:59 UTC
-- GitLab Migration Automatic Message --

This bug has been migrated to freedesktop.org's GitLab instance and has been closed from further activity.

You can subscribe and participate further through the new bug through this link to our GitLab instance: https://gitlab.freedesktop.org/cairo/cairo/issues/35.

Use of freedesktop.org services, including Bugzilla, is subject to our Code of Conduct. How we collect and use information is described in our Privacy Policy.