Graphics Painting question for graphics Gurus.

Graphics Painting question for graphics Gurus.

Post by Xavier Plasenci » Wed, 16 Jun 1999 04:00:00



I am trying to write a graphics program that displays a bitmap(JPEG) on
the screen, with the GGI libary.
After much work and using ggv a sample GGI program I was able to load a
JPEG and display it on a window.
However I am left with a question.

When I tried to display the image using a PutPixel API the color was
messed up and so was the image.  However when I used a PutHLine API
(exact APIs are ggiPutPixel, ggiPutHLine)  The image was properly
displayed  and so where the colors.  When I looked at the intrinics of
ggi to see what it did differently for the
ggiPutHLine it used 2 Xlib commands XCreateImage and XPutImage.
It seems tht XCreate image does some type of ZImage pixel packing to
create the correct colors and pixel width.

If I am correct, does anybody know how algorithm for packing a ZImage
pixel.

 
 
 

Graphics Painting question for graphics Gurus.

Post by Marcus Sundber » Wed, 16 Jun 1999 04:00:00



> I am trying to write a graphics program that displays a bitmap(JPEG) on
> the screen, with the GGI libary.
> After much work and using ggv a sample GGI program I was able to load a
> JPEG and display it on a window.
> However I am left with a question.

> When I tried to display the image using a PutPixel API the color was
> messed up and so was the image.  However when I used a PutHLine API
> (exact APIs are ggiPutPixel, ggiPutHLine)  The image was properly
> displayed  and so where the colors.  When I looked at the intrinics of
> ggi to see what it did differently for the
> ggiPutHLine it used 2 Xlib commands XCreateImage and XPutImage.
> It seems tht XCreate image does some type of ZImage pixel packing to
> create the correct colors and pixel width.

> If I am correct, does anybody know how algorithm for packing a ZImage
> pixel.

The LibGGI API does not have the notion of a ZImage, so this is not
your problem.
Please post the code which fails together with info about your system,
and it may be possible to know what the problem is.

//Marcus
--
-------------------------------+------------------------------------
        Marcus Sundberg        | http://www.stacken.kth.se/~mackan/
 Royal Institute of Technology |       Phone: +46 707 295404


 
 
 

Graphics Painting question for graphics Gurus.

Post by Xavier Plasenci » Fri, 18 Jun 1999 04:00:00




> > I am trying to write a graphics program that displays a bitmap(JPEG) on
> > the screen, with the GGI libary.
> > After much work and using ggv a sample GGI program I was able to load a
> > JPEG and display it on a window.
> > However I am left with a question.

> > When I tried to display the image using a PutPixel API the color was
> > messed up and so was the image.  However when I used a PutHLine API
> > (exact APIs are ggiPutPixel, ggiPutHLine)  The image was properly
> > displayed  and so where the colors.  When I looked at the intrinics of
> > ggi to see what it did differently for the
> > ggiPutHLine it used 2 Xlib commands XCreateImage and XPutImage.
> > It seems tht XCreate image does some type of ZImage pixel packing to
> > create the correct colors and pixel width.

> > If I am correct, does anybody know how algorithm for packing a ZImage
> > pixel.

> The LibGGI API does not have the notion of a ZImage, so this is not
> your problem.

There is the pixel code I used that does not work.

For both snipis "bitmap" is a pointer to a char.
    for(y=0; y < hight; y++)
    {
        for(x=0; x < width ; x++)
        {
        ggiPutPixel(vis, x, y, *(bitmap+((x*gbm.w)+y)));
        }
    }

Here is the code I changed using ggiPutHLine which now works..

    bitmap_width = get_bitmap_width(&gbm);

    work_bitmap  = (byte *) (newBMP+ (gbm.h * bitmap_width));
    work_bitmap  = (byte *) (work_bitmap - (((0 + 1) * bitmap_width) + 0));

    for(y=0; y < gbm.h ; y++)
    {
        ggiPutHLine(vis, 0, y, bitmap_width, work_bitmap);
        work_bitmap = (byte *) (work_bitmap - bitmap_width);
    }

After looking at the code below I new that simply painting a pixel would not
work.
I knew I had to compress the bitmap image.  As I stated earlier I used
sample code
from someones elses code to get the image to display.  I am curios to know
how the
a 16 bit bitmap images compressed to a pixel.

Here is the snipit of X windows code that draws the lines from ggiPutHLine

int GGI_Xlib_puthline(ggi_visual *vis, int x, int y, int w, void *data)
{
    XImage *ximg;

    ximg=XCreateImage(XLIB_PRIV(vis)->display,
              DefaultVisual(XLIB_PRIV(vis)->display, 0),
              LIBGGI_PIXFMT(vis)->size, ZPixmap, 0,
              data, w, 1, 8, 0);
    XPutImage(XLIB_PRIV(vis)->display,
          XLIB_PRIV(vis)->window,
          XLIB_PRIV(vis)->gc,
              ximg, 0, 0, x, y, w, 1);
    XFree(ximg);

    XLIB_DOSYNC(vis);
    return 0;

Here is a snimpit from the SVGA lib

if (w>0) {
        if (SVGA_PRIV(vis)->ismodex && x%4 != 0) {
            for (;x%4 != 0;x++) {
                ggiPutPixel(vis, x, y, *((char*)buffer));
                buffer = ((char*)buffer)+1;
            }
            for (;w%4 != 0;w--)
                ggiPutPixel(vis, x, y, *((char*)buffer+w));

- Show quoted text -

}

> Please post the code which fails together with info about your system,
> and it may be possible to know what the problem is.

> //Marcus
> --
> -------------------------------+------------------------------------
>         Marcus Sundberg        | http://www.stacken.kth.se/~mackan/
>  Royal Institute of Technology |       Phone: +46 707 295404


 
 
 

Graphics Painting question for graphics Gurus.

Post by Marcus Sundber » Fri, 18 Jun 1999 04:00:00




> > The LibGGI API does not have the notion of a ZImage, so this is not
> > your problem.

> There is the pixel code I used that does not work.

> For both snipis "bitmap" is a pointer to a char.
>     for(y=0; y < hight; y++)
>     {
>         for(x=0; x < width ; x++)
>         {
>         ggiPutPixel(vis, x, y, *(bitmap+((x*gbm.w)+y)));

                                 ^^^^^^^^^^^^^^^^^^^^^^^

Quote:>         }
>     }

Here you are reading a single byte from the bitmap, yet you state
below that the bitmap is 16 bits/pixel. Also the math is completely
wrong - it should be ((y*gbm.w)+x).
                       ^        ^
And finally - what mode are the LibGGI visual in? And have you checked
that the pixelformat of the visual is the same as that of the bitmap?
(Use ggiGetPixelFormat())

Quote:> Here is the code I changed using ggiPutHLine which now works..

>     bitmap_width = get_bitmap_width(&gbm);

>     work_bitmap  = (byte *) (newBMP+ (gbm.h * bitmap_width));
>     work_bitmap  = (byte *) (work_bitmap - (((0 + 1) * bitmap_width) + 0));

>     for(y=0; y < gbm.h ; y++)
>     {
>         ggiPutHLine(vis, 0, y, bitmap_width, work_bitmap);
>         work_bitmap = (byte *) (work_bitmap - bitmap_width);
>     }

Your bitmap is upside down? In the first code snippet you increase the
bitmap address for each line, but in this code you decrease it...

Quote:> After looking at the code below I new that simply painting a pixel would not
> work.

Painting a pixel works just fine, but it has to be in the right
format for the mode and visual. The pixel format is the same for
all ggiPut* functions, so if you use correct code both ways will work.
But in any case you should use ggiPutHLine() (or even ggiPutBox()),
because that means far less overhead than if you use ggiPutPixel()
on each pixel.

Quote:> I knew I had to compress the bitmap image.

You don't have to "compress" it, you just have to be sure that the
you pass to the ggiPut* functions are suitable for the current mode.

Quote:> Here is the snipit of X windows code that draws the lines from ggiPutHLine

> int GGI_Xlib_puthline(ggi_visual *vis, int x, int y, int w, void *data)
> {
>     XImage *ximg;

>     ximg=XCreateImage(XLIB_PRIV(vis)->display,
>               DefaultVisual(XLIB_PRIV(vis)->display, 0),
>               LIBGGI_PIXFMT(vis)->size, ZPixmap, 0,
>               data, w, 1, 8, 0);
>     XPutImage(XLIB_PRIV(vis)->display,
>           XLIB_PRIV(vis)->window,
>           XLIB_PRIV(vis)->gc,
>               ximg, 0, 0, x, y, w, 1);
>     XFree(ximg);

>     XLIB_DOSYNC(vis);
>     return 0;

> Here is a snimpit from the SVGA lib

> if (w>0) {
>         if (SVGA_PRIV(vis)->ismodex && x%4 != 0) {
>             for (;x%4 != 0;x++) {
>                 ggiPutPixel(vis, x, y, *((char*)buffer));
>                 buffer = ((char*)buffer)+1;
>             }
>             for (;w%4 != 0;w--)
>                 ggiPutPixel(vis, x, y, *((char*)buffer+w));
> }

Yes, that code looks familiar... ;-)

//Marcus
--
-------------------------------+------------------------------------
        Marcus Sundberg        | http://www.stacken.kth.se/~mackan/
 Royal Institute of Technology |       Phone: +46 707 295404

Posted from a worthless news server
Posted from a worthless news server
Posted from a worthless news server
Posted from a worthless news server
Posted from a worthless news server
Posted from a worthless news server
Posted from a worthless news server
Posted from a worthless news server
Posted from a worthless news server
Posted from a worthless news server
Posted from a worthless news server
Posted from a worthless news server
Posted from a worthless news server
Posted from a worthless news server
Posted from a worthless news server
Posted from a worthless news server

 
 
 

Graphics Painting question for graphics Gurus.

Post by Xavier Plasenci » Fri, 18 Jun 1999 04:00:00


Okay the closest I got to creating  the right image using ggiPutPixel was when I
changed the code below to
this (try to get by the horendious code, I was just trying to get the thing to
work :) )

//This define was taken from GGV
#define MAKE_16_BIT(RED,GREEN,BLUE) (((RED>>3)<<11)|((GREEN>>2)<<5)|(BLUE>>3))

 ggi_pixel gpix, gpix1, gpix2,gpix3;
  int bmpwidht = get_bitmap_width(gbm);

for(y=0; y < hight; y++)
{
   for(x=0; x < width ; x+=3)
   {
    gPix1= *(bitmap + (y*bmpwidth)*x));
    gPix1= *(bitmap + (y*bmpwidth)*x+1));
    gPix1= *(bitmap + (y*bmpwidth)*x+2));
     gpix = MAKE_16_BIT(gpix1,gpix2,gpix3);
    ggiPutPixel(vis, x, y, gpix);
    }
 }

//This function was taken from GGV
int get_bitmap_width(GBM *gbm)
{
//sniped code and only left the 24bit to lenght
                return((((gbm->w * 3) + 3) / 4) * 4);

Quote:}

The quality seemed poor, but the colormap was correct and the image was visible.

Latter in this email, you advised me to stick with ggiPutHLine since the speed is
much faster.
That is ablsolutily true,  the speed difference is noticably different.  However
I am just curious as
to what is the proper way of encodeing char bitmaps to the right pixel depth.

The equation in get_bitmap_width is maigic as far as I am concenred.  How does
that pertain to
the bitmap color depth




> > > The LibGGI API does not have the notion of a ZImage, so this is not
> > > your problem.

> > There is the pixel code I used that does not work.

> > For both snipis "bitmap" is a pointer to a char.
> >     for(y=0; y < hight; y++)
> >     {
> >         for(x=0; x < width ; x++)
> >         {
> >         ggiPutPixel(vis, x, y, *(bitmap+((x*gbm.w)+y)));
>                                  ^^^^^^^^^^^^^^^^^^^^^^^
> >         }
> >     }

> Here you are reading a single byte from the bitmap, yet you state
> below that the bitmap is 16 bits/pixel. Also the math is completely
> wrong - it should be ((y*gbm.w)+x).
>                        ^        ^

Okay that was really dumb of me :)

- Show quoted text -

Quote:

> And finally - what mode are the LibGGI visual in? And have you checked
> that the pixelformat of the visual is the same as that of the bitmap?
> (Use ggiGetPixelFormat())

> > Here is the code I changed using ggiPutHLine which now works..

> >     bitmap_width = get_bitmap_width(&gbm);

> >     work_bitmap  = (byte *) (newBMP+ (gbm.h * bitmap_width));
> >     work_bitmap  = (byte *) (work_bitmap - (((0 + 1) * bitmap_width) + 0));

> >     for(y=0; y < gbm.h ; y++)
> >     {
> >         ggiPutHLine(vis, 0, y, bitmap_width, work_bitmap);
> >         work_bitmap = (byte *) (work_bitmap - bitmap_width);
> >     }

> Your bitmap is upside down? In the first code snippet you increase the
> bitmap address for each line, but in this code you decrease it...

> > After looking at the code below I new that simply painting a pixel would not
> > work.

> Painting a pixel works just fine, but it has to be in the right
> format for the mode and visual. The pixel format is the same for
> all ggiPut* functions, so if you use correct code both ways will work.
> But in any case you should use ggiPutHLine() (or even ggiPutBox()),
> because that means far less overhead than if you use ggiPutPixel()
> on each pixel.

> > I knew I had to compress the bitmap image.

> You don't have to "compress" it, you just have to be sure that the
> you pass to the ggiPut* functions are suitable for the current mode.

> > Here is the snipit of X windows code that draws the lines from ggiPutHLine

> > int GGI_Xlib_puthline(ggi_visual *vis, int x, int y, int w, void *data)
> > {
> >     XImage *ximg;

> >     ximg=XCreateImage(XLIB_PRIV(vis)->display,
> >               DefaultVisual(XLIB_PRIV(vis)->display, 0),
> >               LIBGGI_PIXFMT(vis)->size, ZPixmap, 0,
> >               data, w, 1, 8, 0);
> >     XPutImage(XLIB_PRIV(vis)->display,
> >           XLIB_PRIV(vis)->window,
> >           XLIB_PRIV(vis)->gc,
> >               ximg, 0, 0, x, y, w, 1);
> >     XFree(ximg);

> >     XLIB_DOSYNC(vis);
> >     return 0;

> > Here is a snimpit from the SVGA lib

> > if (w>0) {
> >         if (SVGA_PRIV(vis)->ismodex && x%4 != 0) {
> >             for (;x%4 != 0;x++) {
> >                 ggiPutPixel(vis, x, y, *((char*)buffer));
> >                 buffer = ((char*)buffer)+1;
> >             }
> >             for (;w%4 != 0;w--)
> >                 ggiPutPixel(vis, x, y, *((char*)buffer+w));
> > }

> Yes, that code looks familiar... ;-)

Ah , did you write that code?

- Show quoted text -

> //Marcus
> --
> -------------------------------+------------------------------------
>         Marcus Sundberg        | http://www.stacken.kth.se/~mackan/
>  Royal Institute of Technology |       Phone: +46 707 295404

> Posted from a worthless news server

 
 
 

Graphics Painting question for graphics Gurus.

Post by Marcus Sundber » Sat, 19 Jun 1999 04:00:00



> Okay the closest I got to creating  the right image using ggiPutPixel was when I
> changed the code below to
> this (try to get by the horendious code, I was just trying to get the thing to
> work :) )

> //This define was taken from GGV
> #define MAKE_16_BIT(RED,GREEN,BLUE) (((RED>>3)<<11)|((GREEN>>2)<<5)|(BLUE>>3))

That is broken code. If you don't want to use ggiMapColor() you
need to use ggiGetPixelFormat() to query the pixelformat. Never
make any assumptions like above.

Quote:>  ggi_pixel gpix, gpix1, gpix2,gpix3;
>   int bmpwidht = get_bitmap_width(gbm);

> for(y=0; y < hight; y++)
> {
>    for(x=0; x < width ; x+=3)
>    {
>     gPix1= *(bitmap + (y*bmpwidth)*x));
>     gPix1= *(bitmap + (y*bmpwidth)*x+1));
>     gPix1= *(bitmap + (y*bmpwidth)*x+2));
>      gpix = MAKE_16_BIT(gpix1,gpix2,gpix3);
>     ggiPutPixel(vis, x, y, gpix);
>     }
>  }

Even if you fixed the above so it will compile it wouldn't draw
anything resembling the original image. Aside from only drawing
every third pixel horizontally the (y*bmpwidth)*x needs to be
replaced with (y*bmpwidth)+x.

Something like this is what you want to do:

int linediff = get_bitmap_width(gbm) - width*3;

for (y=0; y < height; y++) {
        for (x=0; x < width; x++) {
                ggi_color col;

                col.r = *bitmap << 8;
                bitmap++;
                col.g = *bitmap << 8;
                bitmap++;
                col.b = *bitmap << 8;
                bitmap++;
                ggiPutPixel(vis, x, y, ggiMapColor(vis, &col));
        }
        bitmap += linediff;

Quote:}
> The equation in get_bitmap_width is maigic as far as I am concenred.  How does
> that pertain to
> the bitmap color depth

It simply multiplies the width in pixels with three and then round
it up to the nearest multiple of four. This will give you the line
length in bytes.

Quote:> > Yes, that code looks familiar... ;-)

> Ah , did you write that code?

Yes.

//Marcus
--
-------------------------------+------------------------------------
        Marcus Sundberg        | http://www.stacken.kth.se/~mackan/
 Royal Institute of Technology |       Phone: +46 707 295404