enigma-cvs
[Top][All Lists]
Advanced

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

[Enigma-cvs] enigma/src/px IMG_SavePNG.c, NONE, 1.1 IMG_SavePNG.h, NONE,


From: Johannes Fortmann <address@hidden>
Subject: [Enigma-cvs] enigma/src/px IMG_SavePNG.c, NONE, 1.1 IMG_SavePNG.h, NONE, 1.1 Makefile.am, 1.7, 1.8 video.cc, 1.11, 1.12 video.hh, 1.6, 1.7
Date: Wed, 19 Nov 2003 16:22:40 +0000

Update of /cvsroot/enigma/enigma/src/px
In directory subversions:/tmp/cvs-serv14797/src/px

Modified Files:
        Makefile.am video.cc video.hh 
Added Files:
        IMG_SavePNG.c IMG_SavePNG.h 
Log Message:
Endian fixes to PNG save code (please test on little-endian)
PNG saving moved to Surface::save_surface


Index: video.cc
===================================================================
RCS file: /cvsroot/enigma/enigma/src/px/video.cc,v
retrieving revision 1.11
retrieving revision 1.12
diff -C2 -d -r1.11 -r1.12
*** video.cc    16 Nov 2003 17:53:30 -0000      1.11
--- video.cc    19 Nov 2003 16:22:38 -0000      1.12
***************
*** 28,32 ****
  #include "SDL_gfxPrimitives.h"
  #include "SDL_rotozoom.h"
! 
  
  #include <cassert>
--- 28,32 ----
  #include "SDL_gfxPrimitives.h"
  #include "SDL_rotozoom.h"
! #include "IMG_SavePNG.h"
  
  #include <cassert>
***************
*** 380,383 ****
--- 380,388 ----
      s_new = zoomSurface( get_surface(), (double)w/width(), 
(double)h/height(), true);
      return Surface::make_surface (s_new);
+ }
+ 
+ void Surface::save_surface (const std::string &filename) const
+ {
+       IMG_SavePNG(m_surface, filename.c_str());
  }
  

Index: video.hh
===================================================================
RCS file: /cvsroot/enigma/enigma/src/px/video.hh,v
retrieving revision 1.6
retrieving revision 1.7
diff -C2 -d -r1.6 -r1.7
*** video.hh    16 Nov 2003 17:56:45 -0000      1.6
--- video.hh    19 Nov 2003 16:22:38 -0000      1.7
***************
*** 161,164 ****
--- 161,166 ----
          SDL_Surface *get_surface() const { return m_surface; }
  
+               void save_surface (const std::string& filename) const;
+               
          /*
          ** Drawable interface

Index: Makefile.am
===================================================================
RCS file: /cvsroot/enigma/enigma/src/px/Makefile.am,v
retrieving revision 1.7
retrieving revision 1.8
diff -C2 -d -r1.7 -r1.8
*** Makefile.am 27 Oct 2003 11:46:45 -0000      1.7
--- Makefile.am 19 Nov 2003 16:22:38 -0000      1.8
***************
*** 4,7 ****
--- 4,8 ----
  
  libpx_a_SOURCES = \
+       IMG_SavePNG.c IMG_SavePNG.h \
        SDL_gfxPrimitives.c             \
        SDL_gfxPrimitives.h             \

--- NEW FILE: IMG_SavePNG.c ---
#include "SDL.h"
#include "IMG_SavePNG.h"
#include "png.h"

#define IMG_SetError(a) SDL_SetError(a)

/* Save a PNG type image to an SDL datasource */
static void png_write_data(png_structp ctx, png_bytep area, png_size_t size)
{
        SDL_RWops *src;
        
        src = (SDL_RWops *)png_get_io_ptr(ctx);
        SDL_RWwrite(src, area, size, 1);
}

static void png_io_flush(png_structp ctx)
{
        SDL_RWops *src;
        
        src = (SDL_RWops *)png_get_io_ptr(ctx);
        /* how do I flush src? */
}

static int png_colortype_from_surface(SDL_Surface *surface)
{
        int colortype = PNG_COLOR_MASK_COLOR; /* grayscale not supported */
        
        if (surface->format->palette)
                colortype |= PNG_COLOR_MASK_PALETTE;
        else if (surface->format->Amask)
                colortype |= PNG_COLOR_MASK_ALPHA;
        
        return colortype;
}

static void png_user_warn(png_structp ctx, png_const_charp str)
{
        fprintf(stderr, "libpng: warning: %s\n", str);
}

static void png_user_error(png_structp ctx, png_const_charp str)
{
        fprintf(stderr, "libpng: error: %s\n", str);
}



int IMG_SavePNG_RW(SDL_Surface *face, SDL_RWops *src)
{
        png_structp png_ptr = 0;
        png_infop info_ptr = 0;
        png_colorp palette = 0;
        png_bytep *row_pointers = 0;
        int i;
        int colortype;
        int result = -1;
        
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
        int rmask = 0x00ff0000;
        int gmask = 0x0000ff00;
        int bmask = 0x000000ff;
        int amask = 0x00000000;
#else
        int rmask = 0x000000ff;
        int gmask = 0x0000ff00;
        int bmask = 0x00ff0000;
        int amask = 0x00000000;
#endif
        
        SDL_Surface *surface = SDL_CreateRGBSurface(SDL_SWSURFACE, face->w, 
face->h, 24,
                                                                rmask, gmask, 
bmask, amask);
        
        SDL_BlitSurface(face, NULL, surface, NULL);
        
        SDL_LockSurface(surface);
        
        png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, 
png_user_error, png_user_warn);
        
        if (png_ptr == NULL)
        {
                IMG_SetError("Couldn't allocate memory for PNG file");
                return -1;
        }
        
        /* Allocate/initialize the image information data.  REQUIRED */
        info_ptr = png_create_info_struct(png_ptr);
        if (info_ptr == NULL)
        {
                IMG_SetError("Couldn't create image information for PNG file");
                goto done;
        }
        
        /* Set error handling. */
        if (setjmp(png_ptr->jmpbuf))
        {
                /* If we get here, we had a problem reading the file */
                IMG_SetError("Error writing the PNG file");
                goto done;
        }
        
        png_set_write_fn(png_ptr, src, png_write_data, png_io_flush);
        
        /* Set the image information here.  Width and height are up to 2^31,
                * bit_depth is one of 1, 2, 4, 8, or 16, but valid values also 
depend on
                * the color_type selected. color_type is one of 
PNG_COLOR_TYPE_GRAY,
                * PNG_COLOR_TYPE_GRAY_ALPHA, PNG_COLOR_TYPE_PALETTE, 
PNG_COLOR_TYPE_RGB,
                * or PNG_COLOR_TYPE_RGB_ALPHA.  interlace is either 
PNG_INTERLACE_NONE or
                * PNG_INTERLACE_ADAM7, and the compression_type and filter_type 
MUST
                * currently be PNG_COMPRESSION_TYPE_BASE and 
PNG_FILTER_TYPE_BASE. REQUIRED
                */
        colortype = png_colortype_from_surface(surface);
        png_set_IHDR(png_ptr, info_ptr, surface->w, surface->h, 8,
                          colortype, PNG_INTERLACE_NONE, 
PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
        
        /* Write the file header information.  REQUIRED */
        png_write_info(png_ptr, info_ptr);
        
        /* pack pixels into bytes */
        png_set_packing(png_ptr);
        
        /* Create the array of pointers to image data */
        row_pointers = (png_bytep*) malloc(sizeof(png_bytep)*surface->h);
        
        if ( (row_pointers == NULL) ) 
        {
                IMG_SetError("Couldn't allocate PNG row pointers");
                goto done;
        }
        
        for (i = 0; i < surface->h; i++)
                row_pointers[i] = (png_bytep)(Uint8 *)surface->pixels + 
i*surface->pitch;
        
        /* write out the entire image data in one call */
        png_write_image(png_ptr, row_pointers);
        png_write_end(png_ptr, info_ptr);
        result = 0;  /* success! */
        
done:
        if (row_pointers)
                        free(row_pointers);
        
        if (info_ptr->palette)
                free(info_ptr->palette);
        
        png_destroy_write_struct(&png_ptr, (png_infopp)NULL);
        
        
        SDL_UnlockSurface(surface);
        SDL_FreeSurface(surface);
        
        return result;
}

int IMG_SavePNG(SDL_Surface *surface, const char *file)
{
    SDL_RWops *out = SDL_RWFromFile(file, "wb");
    int ret;
    if(!out)
                return -1;
    ret = IMG_SavePNG_RW(surface, out);
    SDL_RWclose(out);
    return ret;
}

--- NEW FILE: IMG_SavePNG.h ---
/*
 IMG_SavePNG.h

 Originally a patch to SDL_image, LGPL

 (c) 2001 Darren Grant
 Endian fixes by J. Fortmann
 
*/
#ifndef _IMG_SavePNG_h
#define _IMG_SavePNG_h

#include "SDL.h"

/* Set up for C function definitions, even when using C++ */
#ifdef __cplusplus
extern "C" {
#endif

int IMG_SavePNG_RW(SDL_Surface *face, SDL_RWops *src);  
int IMG_SavePNG(SDL_Surface *surface, const char *file);
        
/* Ends C function definitions when using C++ */
#ifdef __cplusplus
};
#endif

#endif  // _IMG_SavePNG_h




reply via email to

[Prev in Thread] Current Thread [Next in Thread]