Re: [gtk-list] Reading .png files to pixmaps



On 24 May, Alistair Cunningham shouted:
->  
->  I've been playing with using imlib to load .png files to a GdkPixmap. It
->  seems, well, slow and rather bloated - I have no need for saving files,

it's faster than anything 

->  or for filetypes other than png, or scaling, etc. Also, I'd rather users
->  didn't have to have numerous esoteric libraries installed.
->  
->  Would anyone have any code to load .png files using only libpng calls?
->  Re-inventing the wheel isn't fun.

good luck cause that's what you'll have to do.. The majority of imlib's
code (for Imlib its 6114 line sout of 12115 lines) is devoted to
converting 24bit data (ie what u'll get from a png) to depth-depndant
data. You'll basically have to rewrite all of that to handle "every bit
depth" that I've satdown and actually written. the scaling is no extra
code fromt he rendering of 24-> display depth as ti does both at the
same time "on the fly". You are welcome to re-ivetnt the wheel - but
imlib isn't bloated. it does what it needs to as quickly as possible.
if it's slow the you're likely fidn the slowness is infact libpng not
imlib (libnpg is NOT fast - loading a 1024x768 png is considerably
slower than loading the same sized jpeg on all machines i've tried -
this is most liekly due to libz (zlib) if anything)

also rolling your own will require you to handle pseudo and trucolro
differently as turecolro png's (24 bit) dont have colormaps and thus
you will have to generate one - also you'll have to do your own
colormap management in pseudocolor, and in 15,16 and 24bpp have your
own routines to pump pixels out according to RGB ordering, levels etc.
also dithering to reduced entry colormaps in 8bpp or 4bpp or B&W.

your below code also wil be ratehr slow and any code that is "small"
will be horribly slow. there's a reason Imlib has 6k liens devoted to
rendering... speed.

->  
->  
->  Alistair Cunningham.
->  
->  
->  
->  
->  As an aside: Here's what I've been working with. It doesn't work - it
->  won't handle assigning colours correctly. It's horribly inefficient
->  anyway, so I'd rather bin it. However, it should give an idea what I'm
->  after:
->  
->  
->  
->  #include "tc.h"
->  extern widget *mainwin;
->  
->  GdkPixmap *create_gdkpixmap_from_png(char *path, GdkWindow *window, int *w, int *h, gint depth) {
->    png_structp png_ptr;
->    png_infop info_ptr;
->    unsigned char **lines,*ptr2,r,g,b,a;
->    int i,x,y,bit_depth,color_type,interlace_type;
->    png_uint_32 *ww,*hh;
->    FILE *f;
->    GdkPixmap *map;
->    GdkGC *gc;
->    GdkColor colour;
->  
->    f = fopen(path,"rb");
->    if (!f) {
->      return NULL;
->    }
->  
->    png_ptr=png_create_read_struct(PNG_LIBPNG_VER_STRING,NULL,NULL,NULL);
->    if (!png_ptr) return NULL;
->    info_ptr=png_create_info_struct(png_ptr);
->    if (!info_ptr)
->      {
->        png_destroy_read_struct(&png_ptr,NULL,NULL);
->        return NULL;
->      }
->    if (setjmp(png_ptr->jmpbuf))
->      {
->        png_destroy_read_struct(&png_ptr,&info_ptr,NULL);
->        return NULL;
->      }
->    if (info_ptr->color_type==PNG_COLOR_TYPE_RGB_ALPHA)
->      {
->        png_destroy_read_struct(&png_ptr,&info_ptr,NULL);
->        return NULL;
->      }
->    png_init_io(png_ptr,f);
->  
->    png_read_info(png_ptr,info_ptr);
->    ww=(png_uint_32 *)w;hh=(png_uint_32 *)h;
->    png_get_IHDR(png_ptr,info_ptr,ww,hh,&bit_depth,&color_type,&interlace_type,
->                 NULL, NULL);
->  
->    if (color_type==PNG_COLOR_TYPE_PALETTE) png_set_expand(png_ptr);
->    png_set_strip_16(png_ptr);
->    png_set_packing(png_ptr);
->    if (png_get_valid(png_ptr,info_ptr,PNG_INFO_tRNS))
->      png_set_expand(png_ptr);
->    png_set_filler(png_ptr, 0xff, PNG_FILLER_AFTER);
->    *w=info_ptr->width;
->    *h=info_ptr->height;
->  
->    lines = (unsigned char **)malloc( *h * sizeof( unsigned char *) );
->    for (i=0;i<*h;i++) lines[i] = malloc(*w * ( sizeof( unsigned char )*4 ) );
->    png_read_image(png_ptr,lines);
->    png_destroy_read_struct(&png_ptr,&info_ptr,NULL);
->  
->    map = gdk_pixmap_new( window, *w, *h, depth );
->    if (!map) return NULL;
->    gc = gdk_gc_new( window );
->  
->    if (color_type==PNG_COLOR_TYPE_GRAY)
->      {
->        fprintf(stderr,"\n\n\nBlack and white\n\n\n\n");
->        for(y=0;y<*h;y++)
->          {
->            ptr2=lines[y];
->            for(x=0;x<*w;x++)
->              {
->                r=*ptr2++;
->                colour.red = colour.green = colour.blue = r * (65535/255);
->                colour.pixel = (gulong)(r*65536 + r*256 + r);
->                gdk_color_alloc( gtk_widget_get_colormap(mainwin), &colour );
->                gdk_gc_set_foreground( gc, &colour );
->                gdk_draw_point( map, gc, x, y );
->              }
->            }
->      }
->     else
->       {
->  
->  	/* This is the horribly broken bit. The gdk_color_alloc below
->  works, but takes about 30 minutes to load a 256x256 bitmap on a Pentium
->  180. */
->  
->  gdk_colors_alloc( gtk_widget_get_colormap(mainwin), FALSE, (gulong *)info_ptr->palette, info_ptr->num_palette, (gulong *)lines, *w**h );
->         for(y=0;y<*h;y++)
->           {
->             printf("Row %d\n",y);
->              ptr2=lines[y];
->             for(x=0;x<*w;x++)
->                 {
->                   r=*ptr2++;g=*ptr2++;b=*ptr2++;a=*ptr2++;
->                   colour.red = r * 65535/255;
->                   colour.green = g * 65535/255;
->                   colour.blue = b * 65535/255;
->                   colour.pixel = (gulong)(r*65536 + g*256 + b);
->                   // gdk_color_alloc( gtk_widget_get_colormap(mainwin),&colour );
->                   gdk_gc_set_foreground( gc, &colour );
->                   gdk_draw_point( map, gc, x, y );
->                 }
->           }
->       }
->    for (i=0;i<*h;i++) free(lines[i]);
->    free(lines);
->    gdk_gc_destroy( gc );
->  
->    return map;
->  }
->  
->  
->  
->  --------------------------------------------------------------------------
->   Alistair Cunningham   Selwyn College, Cambridge   Email: ac212@cam.ac.uk
->  

-- 
--------------- Codito, ergo sum - "I code, therefore I am" --------------------
raster@rasterman.com       /\___ /\ ___/||\___ ____/|/\___  raster@redhat.com
Carsten Haitzler           | _ //__\\ __||_ __\\ ___|| _ /  Red Hat Advanced
218/21 Conner Drive        || // __ \\_ \ | |   \ _/_|| /   Development Labs
Chapel Hill NC 27514 USA   ||\\\/  \//__/ |_|   /___/||\\   919 547 0012 ext 282
+1 (919) 929 9443, 801 4392   For pure Enlightenmenthttp://www.rasterman.com/ 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]