src/lib/image.c
changeset 0 cff7fac35cc2
child 1 f3cde3db1fef
equal deleted inserted replaced
-1:000000000000 0:cff7fac35cc2
       
     1 #include "image.h"
       
     2 
       
     3 static int pt_image_new (struct pt_image **img_ptr, struct pt_ctx *ctx, const char *png_path)
       
     4 {
       
     5     struct pt_image *img;
       
     6 
       
     7     // alloc
       
     8     if ((img = calloc(1, sizeof(*img))) == NULL)
       
     9         return -1;
       
    10 
       
    11     if ((img->png_path = strdup(png_path)) == NULL)
       
    12         goto error;
       
    13 
       
    14     // init
       
    15     img->ctx = ctx;
       
    16     
       
    17     // ok
       
    18     *img_ptr = img;
       
    19 
       
    20     return 0;
       
    21 
       
    22 error:
       
    23     pt_image_destroy(img);
       
    24 
       
    25     return -1;
       
    26 }
       
    27 
       
    28 /**
       
    29  * Open the image's FILE
       
    30  */
       
    31 static int pt_image_open_file (struct pt_image *img, FILE **file_ptr)
       
    32 {
       
    33     FILE *fp;
       
    34     
       
    35     // open
       
    36     if (fopen(img->png_path, "rb") < 0)
       
    37         return -1;
       
    38 
       
    39     // ok
       
    40     *file_ptr = fp;
       
    41 
       
    42     return 0;
       
    43 }
       
    44 
       
    45 /**
       
    46  * Open the PNG image, setting up the I/O and returning the png_structp and png_infop
       
    47  */
       
    48 static int pt_image_open_png (struct pt_image *img, png_structp *png_ptr, png_infop *info_ptr)
       
    49 {
       
    50     FILE *fp = NULL;
       
    51     png_structp png = NULL;
       
    52     png_infop info = NULL;
       
    53     
       
    54     // open I/O
       
    55     if (pt_image_open_file(img, &fp))
       
    56         goto error;
       
    57 
       
    58     // create the struct
       
    59     if ((png = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL)) == NULL)
       
    60         goto error;
       
    61 
       
    62     // create the info
       
    63     if ((info = png_create_info_struct(png)) == NULL)
       
    64         goto error;
       
    65 
       
    66     // setup error trap for the I/O
       
    67     if (setjmp(png_jmpbuf(png)))
       
    68         goto error;
       
    69     
       
    70     // setup I/O to FILE
       
    71     png_init_io(png, fp);
       
    72 
       
    73     // ok
       
    74     *png_ptr = png;
       
    75     *info_ptr = info;
       
    76 
       
    77     return 0;
       
    78 
       
    79 error:
       
    80     // cleanup file
       
    81     if (fp) fclose(fp);
       
    82 
       
    83     // cleanup PNG state
       
    84     png_destroy_read_struct(&png, &info, NULL);
       
    85 
       
    86     return -1;
       
    87 }
       
    88 
       
    89 /**
       
    90  * Open the PNG image, and write out to the cache
       
    91  */
       
    92 static int pt_image_update_cache (struct pt_image *img)
       
    93 {
       
    94     png_structp png;
       
    95     png_infop info;
       
    96 
       
    97     // open .png
       
    98     if (pt_image_open_png(img, &png, &info))
       
    99         return -1;
       
   100     
       
   101     // setup error trap
       
   102     if (setjmp(png_jmpbuf(png)))
       
   103         goto error;
       
   104 
       
   105     // read meta-info
       
   106     png_read_info(png, info);
       
   107 
       
   108     // pass to cache object
       
   109     if (pt_cache_update_png(img->cache, png, info))
       
   110         goto error;
       
   111 
       
   112     // finish off, ignore trailing data
       
   113     png_read_end(png, NULL);
       
   114 
       
   115     // clean up
       
   116     png_destroy_read_struct(&png, &info);
       
   117 
       
   118     return 0;
       
   119 
       
   120 error:
       
   121     // clean up
       
   122     png_destroy_read_struct(&png, &info);
       
   123 
       
   124     return -1;
       
   125 }
       
   126 
       
   127 int pt_image_open (struct pt_image **img_ptr, struct pt_ctx *ctx, const char *png_path, int cache_mode)
       
   128 {
       
   129     struct pt_image *img;
       
   130 
       
   131     // XXX: verify that the png_path exists and looks like a PNG file
       
   132 
       
   133     // alloc
       
   134     if (pt_image_new(&img, ctx, png_path))
       
   135         return -1;
       
   136 
       
   137     // open the cache object for this image
       
   138     if (pt_cache_open(&img->cache, img, mode))
       
   139         goto error;
       
   140     
       
   141     // update if not fresh
       
   142     if (!pt_cache_fresh(img->cache))
       
   143         pt_image_update_cache(img);
       
   144     
       
   145     // ok, ready for access
       
   146     *img_ptr = img;
       
   147 
       
   148     return 0;
       
   149 
       
   150 error:
       
   151     pt_image_destroy(img);
       
   152 }