render_png.c
changeset 17 8e8b56b0e0f5
parent 15 e7f0697814dc
child 19 d18606bb6f20
equal deleted inserted replaced
16:50995bbe442a 17:8e8b56b0e0f5
     1 #include <stdlib.h>
     1 #include <stdlib.h>
     2 
     2 
     3 #include <png.h>
     3 #include <png.h>
     4 
     4 
     5 #include "common.h"
     5 #include "common.h"
     6 #include "render_internal.h"
     6 #include "render_struct.h"
       
     7 #include "render_png_struct.h"
     7 #include "render_png.h"
     8 #include "render_png.h"
     8 
     9 
     9 struct render_png {
       
    10     // libpng handles
       
    11     png_structp png_ptr;
       
    12     png_infop info_ptr;
       
    13 
       
    14     // some info that we need to keep from the struct render
       
    15     render_ctx_write_cb io_write_fn;
       
    16     render_ctx_flush_cb io_flush_fn;
       
    17     void *cb_arg;
       
    18 };
       
    19 
    10 
    20 static void _render_png_write(png_structp png_ptr, png_bytep data, png_size_t length) {
    11 static void _render_png_write(png_structp png_ptr, png_bytep data, png_size_t length) {
    21     struct render_png *ctx = png_get_io_ptr(png_ptr);
    12     struct render_png *ctx = png_get_io_ptr(png_ptr);
    22 
    13 
    23     if (ctx->io_write_fn)
    14     if (ctx->io_write_fn)
    36             png_error(png_ptr, "_render_png_flush: io_flush_fn");
    27             png_error(png_ptr, "_render_png_flush: io_flush_fn");
    37         }
    28         }
    38 }
    29 }
    39 
    30 
    40 static void _render_png_free (struct render_png *ctx) {
    31 static void _render_png_free (struct render_png *ctx) {
    41     if (ctx)
    32     render_png_deinit(ctx);
    42         png_destroy_write_struct(&ctx->png_ptr, &ctx->info_ptr);
    33     
    43 
    34     if (ctx->owned_by_me)
    44     free(ctx);
    35         free(ctx);
    45 }
    36 }
    46 
    37 
       
    38 int render_png_deinit (struct render_png *ctx) {
       
    39     // not initialized? Just return a positive nonzero value
       
    40     if (!ctx->png_ptr)
       
    41         return 1;
    47 
    42 
    48 struct render_png *render_png_init (struct render *render) {
    43     // libpng error handling
       
    44     if (setjmp(png_jmpbuf(ctx->png_ptr)))
       
    45         ERROR("libpng");
       
    46     
       
    47     png_destroy_write_struct(&ctx->png_ptr, &ctx->info_ptr);
    49 
    48 
    50     struct render_png *ctx = NULL;
    49     // success
       
    50     return 0;
    51 
    51 
    52     // calloc the render_png
    52 error:
    53     if (!(ctx = calloc(1, sizeof(struct render_png))))
    53     free(ctx);
    54         ERROR("calloc");
    54     return -1;
       
    55 }
    55 
    56 
       
    57 /*
       
    58  * Note that it's vitally important not to call any libpng functions directly,
       
    59  * the error-handling setjmp will be invalid.
       
    60  */
       
    61 
       
    62 int render_png_init (struct render_png *ctx, struct render *render) {
    56     // store some info from the struct render
    63     // store some info from the struct render
    57     ctx->io_write_fn = render->io_write_fn;
    64     ctx->io_write_fn = render->io_write_fn;
    58     ctx->io_flush_fn = render->io_flush_fn;
    65     ctx->io_flush_fn = render->io_flush_fn;
    59     ctx->cb_arg = render->cb_arg;
    66     ctx->cb_arg = render->cb_arg;
    60 
    67 
    81     // some PNG metadata
    88     // some PNG metadata
    82     png_set_IHDR(ctx->png_ptr, ctx->info_ptr, render->img_w, render->img_h, 8, PNG_COLOR_TYPE_GRAY, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
    89     png_set_IHDR(ctx->png_ptr, ctx->info_ptr, render->img_w, render->img_h, 8, PNG_COLOR_TYPE_GRAY, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
    83 
    90 
    84     // write out the PNG header
    91     // write out the PNG header
    85     png_write_info(ctx->png_ptr, ctx->info_ptr);
    92     png_write_info(ctx->png_ptr, ctx->info_ptr);
       
    93     
       
    94     // success
       
    95     return 0;
       
    96 
       
    97 error:
       
    98     render_png_deinit(ctx);
       
    99     return -1;
       
   100 }
       
   101 
       
   102 struct render_png *render_png_alloc (struct render *render) {
       
   103     struct render_png *ctx = NULL;
       
   104 
       
   105     // calloc the render_png
       
   106     if (!(ctx = calloc(1, sizeof(struct render_png))))
       
   107         ERROR("calloc");
       
   108     
       
   109     // I need to free it
       
   110     ctx->owned_by_me = 1;
       
   111 
       
   112     // init it
       
   113     if (render_png_init(ctx, render))
       
   114         goto error;
    86 
   115 
    87     // success
   116     // success
    88     return ctx;
   117     return ctx;
    89 
   118 
    90 error:
   119 error: