src/lib/png.c
author Tero Marttila <terom@fixme.fi>
Tue, 26 Jan 2010 16:52:18 +0200
changeset 110 81a0afb4b229
parent 108 b81d2fcfa446
child 111 a31ffb59bc19
permissions -rw-r--r--
change palette range check to assert
56
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     1
#include "png.h" // pt_png header
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     2
#include "error.h"
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     3
#include "shared/log.h" // debug only
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     4
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     5
#include <png.h> // sysmtem libpng header
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     6
#include <assert.h>
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     7
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     8
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     9
#define min(a, b) (((a) < (b)) ? (a) : (b))
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    10
69
1d188aa94aee pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents: 61
diff changeset
    11
int pt_png_check (const char *path)
1d188aa94aee pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents: 61
diff changeset
    12
{
1d188aa94aee pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents: 61
diff changeset
    13
    FILE *fp;
1d188aa94aee pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents: 61
diff changeset
    14
    uint8_t header[8];
1d188aa94aee pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents: 61
diff changeset
    15
    int ret;
1d188aa94aee pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents: 61
diff changeset
    16
1d188aa94aee pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents: 61
diff changeset
    17
    // fopen
1d188aa94aee pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents: 61
diff changeset
    18
    if ((fp = fopen(path, "rb")) == NULL)
1d188aa94aee pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents: 61
diff changeset
    19
        RETURN_ERROR(PT_ERR_IMG_OPEN);
1d188aa94aee pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents: 61
diff changeset
    20
1d188aa94aee pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents: 61
diff changeset
    21
    // read
1d188aa94aee pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents: 61
diff changeset
    22
    if (fread(header, 1, sizeof(header), fp) != sizeof(header))
1d188aa94aee pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents: 61
diff changeset
    23
        JUMP_SET_ERROR(ret, PT_ERR_IMG_FORMAT);
1d188aa94aee pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents: 61
diff changeset
    24
      
1d188aa94aee pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents: 61
diff changeset
    25
    // compare signature  
1d188aa94aee pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents: 61
diff changeset
    26
    if (png_sig_cmp(header, 0, sizeof(header)))
1d188aa94aee pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents: 61
diff changeset
    27
        // not a PNG file
1d188aa94aee pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents: 61
diff changeset
    28
        ret = 1;
1d188aa94aee pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents: 61
diff changeset
    29
1d188aa94aee pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents: 61
diff changeset
    30
    else
1d188aa94aee pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents: 61
diff changeset
    31
        // valid PNG file
1d188aa94aee pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents: 61
diff changeset
    32
        ret = 0;
1d188aa94aee pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents: 61
diff changeset
    33
1d188aa94aee pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents: 61
diff changeset
    34
error:
1d188aa94aee pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents: 61
diff changeset
    35
    // cleanup
1d188aa94aee pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents: 61
diff changeset
    36
    fclose(fp);
1d188aa94aee pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents: 61
diff changeset
    37
1d188aa94aee pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents: 61
diff changeset
    38
    return ret;
1d188aa94aee pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents: 61
diff changeset
    39
}
1d188aa94aee pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents: 61
diff changeset
    40
56
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    41
int pt_png_open (struct pt_image *image, struct pt_png_img *img)
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    42
{
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    43
    int err;
69
1d188aa94aee pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents: 61
diff changeset
    44
1d188aa94aee pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents: 61
diff changeset
    45
    // init
1d188aa94aee pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents: 61
diff changeset
    46
    memset(img, 0, sizeof(*img));
56
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    47
    
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    48
    // open I/O
69
1d188aa94aee pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents: 61
diff changeset
    49
    if ((err = pt_image_open_file(image, &img->fh)))
56
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    50
        JUMP_ERROR(err);
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    51
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    52
    // create the struct
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    53
    if ((img->png = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL)) == NULL)
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    54
        JUMP_SET_ERROR(err, PT_ERR_PNG_CREATE);
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    55
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    56
    // create the info
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    57
    if ((img->info = png_create_info_struct(img->png)) == NULL)
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    58
        JUMP_SET_ERROR(err, PT_ERR_PNG_CREATE);
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    59
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    60
    // setup error trap for the I/O
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    61
    if (setjmp(png_jmpbuf(img->png)))
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    62
        JUMP_SET_ERROR(err, PT_ERR_PNG);
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    63
    
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    64
    // setup error trap
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    65
    if (setjmp(png_jmpbuf(img->png)))
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    66
        JUMP_SET_ERROR(err, PT_ERR_PNG);
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    67
    
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    68
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    69
    // setup I/O to FILE
69
1d188aa94aee pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents: 61
diff changeset
    70
    png_init_io(img->png, img->fh);
56
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    71
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    72
    // read meta-info
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    73
    png_read_info(img->png, img->info);
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    74
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    75
69
1d188aa94aee pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents: 61
diff changeset
    76
    // img->fh will be closed by pt_png_release_read
56
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    77
    return 0;
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    78
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    79
error:
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    80
    // cleanup
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    81
    pt_png_release_read(img);
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    82
    
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    83
    return err;
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    84
}
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    85
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    86
int pt_png_read_header (struct pt_png_img *img, struct pt_png_header *header, size_t *data_size)
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    87
{
69
1d188aa94aee pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents: 61
diff changeset
    88
    // check image doesn't use any options we don't handle
1d188aa94aee pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents: 61
diff changeset
    89
    if (png_get_interlace_type(img->png, img->info) != PNG_INTERLACE_NONE) {
1d188aa94aee pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents: 61
diff changeset
    90
        log_warn("Can't handle interlaced PNG");
1d188aa94aee pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents: 61
diff changeset
    91
1d188aa94aee pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents: 61
diff changeset
    92
        RETURN_ERROR(PT_ERR_IMG_FORMAT);
1d188aa94aee pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents: 61
diff changeset
    93
    }
1d188aa94aee pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents: 61
diff changeset
    94
56
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    95
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    96
    // initialize
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    97
    memset(header, 0, sizeof(*header));
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    98
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    99
    // fill in basic info
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   100
    header->width = png_get_image_width(img->png, img->info);
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   101
    header->height = png_get_image_height(img->png, img->info);
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   102
    header->bit_depth = png_get_bit_depth(img->png, img->info);
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   103
    header->color_type = png_get_color_type(img->png, img->info);
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   104
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   105
    log_debug("width=%u, height=%u, bit_depth=%u, color_type=%u", 
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   106
            header->width, header->height, header->bit_depth, header->color_type
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   107
    );
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   108
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   109
    // only pack 1 pixel per byte, changes rowbytes
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   110
    if (header->bit_depth < 8)
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   111
        png_set_packing(img->png);
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   112
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   113
    // fill in other info
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   114
    header->row_bytes = png_get_rowbytes(img->png, img->info);
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   115
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   116
    // calculate bpp as num_channels * bpc
69
1d188aa94aee pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents: 61
diff changeset
   117
    // this assumes the packed bit depth will be either 8 or 16
56
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   118
    header->col_bytes = png_get_channels(img->png, img->info) * (header->bit_depth == 16 ? 2 : 1);
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   119
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   120
    log_debug("row_bytes=%u, col_bytes=%u", header->row_bytes, header->col_bytes);
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   121
    
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   122
    // palette etc.
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   123
    if (header->color_type == PNG_COLOR_TYPE_PALETTE) {
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   124
        int num_palette;
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   125
        png_colorp palette;
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   126
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   127
        if (png_get_PLTE(img->png, img->info, &palette, &num_palette) == 0)
69
1d188aa94aee pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents: 61
diff changeset
   128
            // PLTE chunk not read?
56
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   129
            RETURN_ERROR(PT_ERR_PNG);
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   130
        
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   131
        // should only be 256 of them at most
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   132
        assert(num_palette <= PNG_MAX_PALETTE_LENGTH);
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   133
    
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   134
        // copy
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   135
        header->num_palette = num_palette;
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   136
        memcpy(&header->palette, palette, num_palette * sizeof(*palette));
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   137
        
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   138
        log_debug("num_palette=%u", num_palette);
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   139
    }
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   140
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   141
    // calculate data size
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   142
    *data_size = header->height * header->row_bytes;
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   143
    
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   144
    return 0;
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   145
}
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   146
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   147
/**
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   148
 * Decode the PNG data directly to memory - not good for sparse backgrounds
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   149
 */
61
31650ef395d3 use pt_png_decode_direct if no background color is set..
Tero Marttila <terom@fixme.fi>
parents: 56
diff changeset
   150
static int pt_png_decode_direct (struct pt_png_img *img, const struct pt_png_header *header, const struct pt_image_params *params, uint8_t *out)
56
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   151
{
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   152
    // write out raw image data a row at a time
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   153
    for (size_t row = 0; row < header->height; row++) {
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   154
        // read row data, non-interlaced
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   155
        png_read_row(img->png, out + row * header->row_bytes, NULL);
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   156
    }
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   157
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   158
    return 0;
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   159
}
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   160
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   161
/**
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   162
 * Decode the PNG data, filtering it for sparse regions
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   163
 */
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   164
static int pt_png_decode_sparse (struct pt_png_img *img, const struct pt_png_header *header, const struct pt_image_params *params, uint8_t *out)
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   165
{
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   166
    // one row of pixel data
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   167
    uint8_t *row_buf;
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   168
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   169
    // alloc
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   170
    if ((row_buf = malloc(header->row_bytes)) == NULL)
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   171
        RETURN_ERROR(PT_ERR_MEM);
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   172
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   173
    // decode each row at a time
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   174
    for (size_t row = 0; row < header->height; row++) {
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   175
        // read row data, non-interlaced
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   176
        png_read_row(img->png, row_buf, NULL);
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   177
        
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   178
        // skip background-colored regions to keep the cache file sparse
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   179
        // ...in blocks of PT_CACHE_BLOCK_SIZE bytes
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   180
        for (size_t col_base = 0; col_base < header->width; col_base += PT_IMG_BLOCK_SIZE) {
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   181
            // size of this block in bytes
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   182
            size_t block_size = min(PT_IMG_BLOCK_SIZE * header->col_bytes, header->row_bytes - col_base);
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   183
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   184
            // ...each pixel
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   185
            for (
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   186
                    size_t col = col_base;
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   187
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   188
                    // BLOCK_SIZE * col_bytes wide, don't go over the edge
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   189
                    col < col_base + block_size; 
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   190
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   191
                    col += header->col_bytes
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   192
            ) {
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   193
                // test this pixel
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   194
                if (bcmp(row_buf + col, params->background_color, header->col_bytes)) {
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   195
                    // differs
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   196
                    memcpy(
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   197
                            out + row * header->row_bytes + col_base, 
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   198
                            row_buf + col_base,
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   199
                            block_size
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   200
                    );
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   201
                    
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   202
                    // skip to next block
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   203
                    break;
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   204
                }
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   205
            }
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   206
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   207
            // skip this block
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   208
            continue;
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   209
        }
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   210
    }
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   211
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   212
    return 0;
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   213
}
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   214
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   215
int pt_png_decode (struct pt_png_img *img, const struct pt_png_header *header, const struct pt_image_params *params, uint8_t *out)
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   216
{
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   217
    int err;
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   218
61
31650ef395d3 use pt_png_decode_direct if no background color is set..
Tero Marttila <terom@fixme.fi>
parents: 56
diff changeset
   219
    // decode
108
b81d2fcfa446 handle the png_color as a pointer in png_pixel_data
Tero Marttila <terom@fixme.fi>
parents: 100
diff changeset
   220
    // XXX: it's an array, you silly
61
31650ef395d3 use pt_png_decode_direct if no background color is set..
Tero Marttila <terom@fixme.fi>
parents: 56
diff changeset
   221
    if (params->background_color)
31650ef395d3 use pt_png_decode_direct if no background color is set..
Tero Marttila <terom@fixme.fi>
parents: 56
diff changeset
   222
        err = pt_png_decode_sparse(img, header, params, out);
31650ef395d3 use pt_png_decode_direct if no background color is set..
Tero Marttila <terom@fixme.fi>
parents: 56
diff changeset
   223
31650ef395d3 use pt_png_decode_direct if no background color is set..
Tero Marttila <terom@fixme.fi>
parents: 56
diff changeset
   224
    else
31650ef395d3 use pt_png_decode_direct if no background color is set..
Tero Marttila <terom@fixme.fi>
parents: 56
diff changeset
   225
        err = pt_png_decode_direct(img, header, params, out);
31650ef395d3 use pt_png_decode_direct if no background color is set..
Tero Marttila <terom@fixme.fi>
parents: 56
diff changeset
   226
    
31650ef395d3 use pt_png_decode_direct if no background color is set..
Tero Marttila <terom@fixme.fi>
parents: 56
diff changeset
   227
    if (err)
56
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   228
        return err;
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   229
    
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   230
    // finish off, ignore trailing data
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   231
    png_read_end(img->png, NULL);
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   232
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   233
    return 0;
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   234
}
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   235
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   236
int pt_png_info (struct pt_png_header *header, struct pt_image_info *info)
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   237
{
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   238
    // fill in info from header
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   239
    info->img_width = header->width;
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   240
    info->img_height = header->height;
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   241
    info->img_bpp = header->bit_depth;
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   242
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   243
    return 0;
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   244
}
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   245
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   246
/** 
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   247
 * libpng I/O callback: write out data
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   248
 */
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   249
static void pt_png_mem_write (png_structp png, png_bytep data, png_size_t length)
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   250
{
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   251
    struct pt_tile_mem *buf = png_get_io_ptr(png);
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   252
    int err;
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   253
    
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   254
    // write to buffer
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   255
    if ((err = pt_tile_mem_write(buf, data, length)))
69
1d188aa94aee pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents: 61
diff changeset
   256
        // drop err, because png_error doesn't do formatted output
56
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   257
        png_error(png, "pt_tile_mem_write: ...");
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   258
}
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   259
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   260
/** 
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   261
 * libpng I/O callback: flush buffered data
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   262
 */
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   263
static void pt_png_mem_flush (png_structp png_ptr)
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   264
{
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   265
    // no-op
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   266
}
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   267
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   268
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   269
/**
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   270
 * Return a pointer to the pixel data on \a row, starting at \a col.
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   271
 */
70
35515b3a82b7 more constness for pt_png
Tero Marttila <terom@fixme.fi>
parents: 69
diff changeset
   272
static inline const void* tile_row_col (const struct pt_png_header *header, const uint8_t *data, size_t row, size_t col)
56
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   273
{
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   274
    return data + (row * header->row_bytes) + (col * header->col_bytes);
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   275
}
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   276
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   277
/**
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   278
 * Write raw tile image data, directly from the cache
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   279
 */
70
35515b3a82b7 more constness for pt_png
Tero Marttila <terom@fixme.fi>
parents: 69
diff changeset
   280
static int pt_png_encode_direct (struct pt_png_img *img, const struct pt_png_header *header, const uint8_t *data, const struct pt_tile_info *ti)
56
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   281
{
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   282
    for (size_t row = ti->y; row < ti->y + ti->height; row++)
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   283
        // write data directly
70
35515b3a82b7 more constness for pt_png
Tero Marttila <terom@fixme.fi>
parents: 69
diff changeset
   284
        // missing const...
35515b3a82b7 more constness for pt_png
Tero Marttila <terom@fixme.fi>
parents: 69
diff changeset
   285
        png_write_row(img->png, (const png_bytep) tile_row_col(header, data, row, ti->x));
56
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   286
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   287
    return 0;
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   288
}
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   289
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   290
/**
100
aee9d0b12fe9 void png_pixel_data, slight restructuring
Tero Marttila <terom@fixme.fi>
parents: 97
diff changeset
   291
 * Fill in a clipped region of \a width_px pixels at the given row segment
aee9d0b12fe9 void png_pixel_data, slight restructuring
Tero Marttila <terom@fixme.fi>
parents: 97
diff changeset
   292
 */
aee9d0b12fe9 void png_pixel_data, slight restructuring
Tero Marttila <terom@fixme.fi>
parents: 97
diff changeset
   293
static inline void tile_row_fill_clip (const struct pt_png_header *header, png_byte *row, size_t width_px)
aee9d0b12fe9 void png_pixel_data, slight restructuring
Tero Marttila <terom@fixme.fi>
parents: 97
diff changeset
   294
{
aee9d0b12fe9 void png_pixel_data, slight restructuring
Tero Marttila <terom@fixme.fi>
parents: 97
diff changeset
   295
    // XXX: use a configureable background color, or full transparency?
aee9d0b12fe9 void png_pixel_data, slight restructuring
Tero Marttila <terom@fixme.fi>
parents: 97
diff changeset
   296
    memset(row, /* 0xd7 */ 0x00, width_px * header->col_bytes);
aee9d0b12fe9 void png_pixel_data, slight restructuring
Tero Marttila <terom@fixme.fi>
parents: 97
diff changeset
   297
}
aee9d0b12fe9 void png_pixel_data, slight restructuring
Tero Marttila <terom@fixme.fi>
parents: 97
diff changeset
   298
aee9d0b12fe9 void png_pixel_data, slight restructuring
Tero Marttila <terom@fixme.fi>
parents: 97
diff changeset
   299
/**
56
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   300
 * Write clipped tile image data (a tile that goes over the edge of the actual image) by aligning the data from the cache as needed
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   301
 */
70
35515b3a82b7 more constness for pt_png
Tero Marttila <terom@fixme.fi>
parents: 69
diff changeset
   302
static int pt_png_encode_clipped (struct pt_png_img *img, const struct pt_png_header *header, const uint8_t *data, const struct pt_tile_info *ti)
56
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   303
{
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   304
    png_byte *rowbuf;
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   305
    size_t row;
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   306
    
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   307
    // image data goes from (ti->x ... clip_x, ti->y ... clip_y), remaining region is filled
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   308
    size_t clip_x, clip_y;
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   309
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   310
69
1d188aa94aee pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents: 61
diff changeset
   311
    // fit the left/bottom edge against the image dimensions
1d188aa94aee pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents: 61
diff changeset
   312
    clip_x = min(ti->x + ti->width, header->width);
1d188aa94aee pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents: 61
diff changeset
   313
    clip_y = min(ti->y + ti->height, header->height);
56
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   314
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   315
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   316
    // allocate buffer for a single row of image data
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   317
    if ((rowbuf = malloc(ti->width * header->col_bytes)) == NULL)
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   318
        RETURN_ERROR(PT_ERR_MEM);
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   319
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   320
    // how much data we actually have for each row, in px and bytes
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   321
    // from [(tile x)---](clip x)
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   322
    size_t row_px = clip_x - ti->x;
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   323
    size_t row_bytes = row_px * header->col_bytes;
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   324
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   325
    // write the rows that we have
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   326
    // from [(tile y]---](clip y)
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   327
    for (row = ti->y; row < clip_y; row++) {
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   328
        // copy in the actual tile data...
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   329
        memcpy(rowbuf, tile_row_col(header, data, row, ti->x), row_bytes);
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   330
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   331
        // generate the data for the remaining, clipped, columns
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   332
        tile_row_fill_clip(header, rowbuf + row_bytes, (ti->width - row_px));
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   333
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   334
        // write
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   335
        png_write_row(img->png, rowbuf);
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   336
    }
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   337
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   338
    // generate the data for the remaining, clipped, rows
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   339
    tile_row_fill_clip(header, rowbuf, ti->width);
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   340
    
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   341
    // write out the remaining rows as clipped data
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   342
    for (; row < ti->y + ti->height; row++)
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   343
        png_write_row(img->png, rowbuf);
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   344
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   345
    // ok
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   346
    return 0;
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   347
}
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   348
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   349
/**
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   350
 * Write unscaled tile data
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   351
 */
70
35515b3a82b7 more constness for pt_png
Tero Marttila <terom@fixme.fi>
parents: 69
diff changeset
   352
static int pt_png_encode_unzoomed (struct pt_png_img *img, const struct pt_png_header *header, const uint8_t *data, const struct pt_tile_info *ti)
56
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   353
{
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   354
    int err;
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   355
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   356
    // set basic info
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   357
    png_set_IHDR(img->png, img->info, ti->width, ti->height, header->bit_depth, header->color_type,
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   358
            PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   359
    );
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   360
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   361
    // set palette?
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   362
    if (header->color_type == PNG_COLOR_TYPE_PALETTE)
61
31650ef395d3 use pt_png_decode_direct if no background color is set..
Tero Marttila <terom@fixme.fi>
parents: 56
diff changeset
   363
        // oops... missing const
31650ef395d3 use pt_png_decode_direct if no background color is set..
Tero Marttila <terom@fixme.fi>
parents: 56
diff changeset
   364
        png_set_PLTE(img->png, img->info, (png_colorp) header->palette, header->num_palette);
56
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   365
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   366
    // write meta-info
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   367
    png_write_info(img->png, img->info);
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   368
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   369
    // our pixel data is packed into 1 pixel per byte (8bpp or 16bpp)
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   370
    png_set_packing(img->png);
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   371
    
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   372
    // figure out if the tile clips
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   373
    if (ti->x + ti->width <= header->width && ti->y + ti->height <= header->height)
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   374
        // doesn't clip, just use the raw data
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   375
        err = pt_png_encode_direct(img, header, data, ti);
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   376
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   377
    else
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   378
        // fill in clipped regions
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   379
        err = pt_png_encode_clipped(img, header, data, ti);
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   380
    
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   381
    return err;
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   382
}
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   383
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   384
/**
100
aee9d0b12fe9 void png_pixel_data, slight restructuring
Tero Marttila <terom@fixme.fi>
parents: 97
diff changeset
   385
 * Manipulate powers of two
aee9d0b12fe9 void png_pixel_data, slight restructuring
Tero Marttila <terom@fixme.fi>
parents: 97
diff changeset
   386
 */
aee9d0b12fe9 void png_pixel_data, slight restructuring
Tero Marttila <terom@fixme.fi>
parents: 97
diff changeset
   387
static inline size_t scale_by_zoom_factor (size_t value, int z)
aee9d0b12fe9 void png_pixel_data, slight restructuring
Tero Marttila <terom@fixme.fi>
parents: 97
diff changeset
   388
{
aee9d0b12fe9 void png_pixel_data, slight restructuring
Tero Marttila <terom@fixme.fi>
parents: 97
diff changeset
   389
    if (z > 0)
aee9d0b12fe9 void png_pixel_data, slight restructuring
Tero Marttila <terom@fixme.fi>
parents: 97
diff changeset
   390
        return value << z;
aee9d0b12fe9 void png_pixel_data, slight restructuring
Tero Marttila <terom@fixme.fi>
parents: 97
diff changeset
   391
aee9d0b12fe9 void png_pixel_data, slight restructuring
Tero Marttila <terom@fixme.fi>
parents: 97
diff changeset
   392
    else if (z < 0)
aee9d0b12fe9 void png_pixel_data, slight restructuring
Tero Marttila <terom@fixme.fi>
parents: 97
diff changeset
   393
        return value >> -z;
aee9d0b12fe9 void png_pixel_data, slight restructuring
Tero Marttila <terom@fixme.fi>
parents: 97
diff changeset
   394
aee9d0b12fe9 void png_pixel_data, slight restructuring
Tero Marttila <terom@fixme.fi>
parents: 97
diff changeset
   395
    else
aee9d0b12fe9 void png_pixel_data, slight restructuring
Tero Marttila <terom@fixme.fi>
parents: 97
diff changeset
   396
        return value;
aee9d0b12fe9 void png_pixel_data, slight restructuring
Tero Marttila <terom@fixme.fi>
parents: 97
diff changeset
   397
}
aee9d0b12fe9 void png_pixel_data, slight restructuring
Tero Marttila <terom@fixme.fi>
parents: 97
diff changeset
   398
aee9d0b12fe9 void png_pixel_data, slight restructuring
Tero Marttila <terom@fixme.fi>
parents: 97
diff changeset
   399
#define ADD_AVG(l, r) (l) = ((l) + (r)) / 2
aee9d0b12fe9 void png_pixel_data, slight restructuring
Tero Marttila <terom@fixme.fi>
parents: 97
diff changeset
   400
aee9d0b12fe9 void png_pixel_data, slight restructuring
Tero Marttila <terom@fixme.fi>
parents: 97
diff changeset
   401
/**
aee9d0b12fe9 void png_pixel_data, slight restructuring
Tero Marttila <terom@fixme.fi>
parents: 97
diff changeset
   402
 * Converts a pixel's data into a png_color
aee9d0b12fe9 void png_pixel_data, slight restructuring
Tero Marttila <terom@fixme.fi>
parents: 97
diff changeset
   403
 */
108
b81d2fcfa446 handle the png_color as a pointer in png_pixel_data
Tero Marttila <terom@fixme.fi>
parents: 100
diff changeset
   404
static inline void png_pixel_data (const png_color **outp, const struct pt_png_header *header, const uint8_t *data, size_t row, size_t col)
100
aee9d0b12fe9 void png_pixel_data, slight restructuring
Tero Marttila <terom@fixme.fi>
parents: 97
diff changeset
   405
{
aee9d0b12fe9 void png_pixel_data, slight restructuring
Tero Marttila <terom@fixme.fi>
parents: 97
diff changeset
   406
    if (header->color_type == PNG_COLOR_TYPE_PALETTE) {
aee9d0b12fe9 void png_pixel_data, slight restructuring
Tero Marttila <terom@fixme.fi>
parents: 97
diff changeset
   407
        // palette entry number
aee9d0b12fe9 void png_pixel_data, slight restructuring
Tero Marttila <terom@fixme.fi>
parents: 97
diff changeset
   408
        int p;
aee9d0b12fe9 void png_pixel_data, slight restructuring
Tero Marttila <terom@fixme.fi>
parents: 97
diff changeset
   409
aee9d0b12fe9 void png_pixel_data, slight restructuring
Tero Marttila <terom@fixme.fi>
parents: 97
diff changeset
   410
        if (header->bit_depth == 8)
aee9d0b12fe9 void png_pixel_data, slight restructuring
Tero Marttila <terom@fixme.fi>
parents: 97
diff changeset
   411
            p = *((uint8_t *) tile_row_col(header, data, row, col));
aee9d0b12fe9 void png_pixel_data, slight restructuring
Tero Marttila <terom@fixme.fi>
parents: 97
diff changeset
   412
        else
aee9d0b12fe9 void png_pixel_data, slight restructuring
Tero Marttila <terom@fixme.fi>
parents: 97
diff changeset
   413
            // unknown
aee9d0b12fe9 void png_pixel_data, slight restructuring
Tero Marttila <terom@fixme.fi>
parents: 97
diff changeset
   414
            return;
aee9d0b12fe9 void png_pixel_data, slight restructuring
Tero Marttila <terom@fixme.fi>
parents: 97
diff changeset
   415
110
81a0afb4b229 change palette range check to assert
Tero Marttila <terom@fixme.fi>
parents: 108
diff changeset
   416
        // hrhr - assume our working data is valid (or we have 255 palette entries, so it doesn't matter...)
81a0afb4b229 change palette range check to assert
Tero Marttila <terom@fixme.fi>
parents: 108
diff changeset
   417
        assert(p < header->num_palette);
100
aee9d0b12fe9 void png_pixel_data, slight restructuring
Tero Marttila <terom@fixme.fi>
parents: 97
diff changeset
   418
        
aee9d0b12fe9 void png_pixel_data, slight restructuring
Tero Marttila <terom@fixme.fi>
parents: 97
diff changeset
   419
        // reference data from palette
108
b81d2fcfa446 handle the png_color as a pointer in png_pixel_data
Tero Marttila <terom@fixme.fi>
parents: 100
diff changeset
   420
        *outp = &header->palette[p];
100
aee9d0b12fe9 void png_pixel_data, slight restructuring
Tero Marttila <terom@fixme.fi>
parents: 97
diff changeset
   421
aee9d0b12fe9 void png_pixel_data, slight restructuring
Tero Marttila <terom@fixme.fi>
parents: 97
diff changeset
   422
    } else {
aee9d0b12fe9 void png_pixel_data, slight restructuring
Tero Marttila <terom@fixme.fi>
parents: 97
diff changeset
   423
        // unknown
aee9d0b12fe9 void png_pixel_data, slight restructuring
Tero Marttila <terom@fixme.fi>
parents: 97
diff changeset
   424
    }
aee9d0b12fe9 void png_pixel_data, slight restructuring
Tero Marttila <terom@fixme.fi>
parents: 97
diff changeset
   425
}
aee9d0b12fe9 void png_pixel_data, slight restructuring
Tero Marttila <terom@fixme.fi>
parents: 97
diff changeset
   426
aee9d0b12fe9 void png_pixel_data, slight restructuring
Tero Marttila <terom@fixme.fi>
parents: 97
diff changeset
   427
/**
56
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   428
 * Write scaled tile data
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   429
 */
70
35515b3a82b7 more constness for pt_png
Tero Marttila <terom@fixme.fi>
parents: 69
diff changeset
   430
static int pt_png_encode_zoomed (struct pt_png_img *img, const struct pt_png_header *header, const uint8_t *data, const struct pt_tile_info *ti)
56
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   431
{
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   432
    // size of the image data in px
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   433
    size_t data_width = scale_by_zoom_factor(ti->width, -ti->zoom);
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   434
    size_t data_height = scale_by_zoom_factor(ti->height, -ti->zoom);
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   435
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   436
    // input pixels per output pixel
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   437
    size_t pixel_size = scale_by_zoom_factor(1, -ti->zoom);
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   438
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   439
    // bytes per output pixel
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   440
    size_t pixel_bytes = 3;
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   441
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   442
    // size of the output tile in px
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   443
    size_t row_width = ti->width;
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   444
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   445
    // size of an output row in bytes (RGB)
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   446
    size_t row_bytes = row_width * 3;
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   447
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   448
    // buffer to hold output rows
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   449
    uint8_t *row_buf;
100
aee9d0b12fe9 void png_pixel_data, slight restructuring
Tero Marttila <terom@fixme.fi>
parents: 97
diff changeset
   450
                
108
b81d2fcfa446 handle the png_color as a pointer in png_pixel_data
Tero Marttila <terom@fixme.fi>
parents: 100
diff changeset
   451
    // color entry for pixel
b81d2fcfa446 handle the png_color as a pointer in png_pixel_data
Tero Marttila <terom@fixme.fi>
parents: 100
diff changeset
   452
    const png_color *c = &header->palette[0];
56
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   453
    
69
1d188aa94aee pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents: 61
diff changeset
   454
    // only supports zooming out...
56
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   455
    if (ti->zoom >= 0)
86
d4a62899587f PT_ERR_TILE_DIM and PT_ERR_TILE_ZOOM
Tero Marttila <terom@fixme.fi>
parents: 84
diff changeset
   456
        RETURN_ERROR(PT_ERR_TILE_ZOOM);
56
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   457
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   458
    if ((row_buf = malloc(row_bytes)) == NULL)
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   459
        RETURN_ERROR(PT_ERR_MEM);
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   460
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   461
    // suppress warning...
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   462
    (void) data_height;
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   463
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   464
    // define pixel format: 8bpp RGB
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   465
    png_set_IHDR(img->png, img->info, ti->width, ti->height, 8, PNG_COLOR_TYPE_RGB,
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   466
            PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   467
    );
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   468
    
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   469
    // write meta-info
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   470
    png_write_info(img->png, img->info);
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   471
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   472
    // ...each output row
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   473
    for (size_t out_row = 0; out_row < ti->height; out_row++) {
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   474
        memset(row_buf, 0, row_bytes);
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   475
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   476
        // ...includes pixels starting from this row.
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   477
        size_t in_row_offset = ti->y + scale_by_zoom_factor(out_row, -ti->zoom);
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   478
        
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   479
        // ...each out row includes pixel_size in rows
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   480
        for (size_t in_row = in_row_offset; in_row < in_row_offset + pixel_size && in_row < header->height; in_row++) {
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   481
            // and includes each input pixel
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   482
            for (size_t in_col = ti->x; in_col < ti->x + data_width && in_col < header->width; in_col++) {
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   483
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   484
                // ...for this output pixel
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   485
                size_t out_col = scale_by_zoom_factor(in_col - ti->x, ti->zoom);
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   486
                
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   487
                // get pixel RGB data
100
aee9d0b12fe9 void png_pixel_data, slight restructuring
Tero Marttila <terom@fixme.fi>
parents: 97
diff changeset
   488
                png_pixel_data(&c, header, data, in_row, in_col);
56
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   489
                
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   490
                // average the RGB data        
108
b81d2fcfa446 handle the png_color as a pointer in png_pixel_data
Tero Marttila <terom@fixme.fi>
parents: 100
diff changeset
   491
                ADD_AVG(row_buf[out_col * pixel_bytes + 0], c->red);
b81d2fcfa446 handle the png_color as a pointer in png_pixel_data
Tero Marttila <terom@fixme.fi>
parents: 100
diff changeset
   492
                ADD_AVG(row_buf[out_col * pixel_bytes + 1], c->green);
b81d2fcfa446 handle the png_color as a pointer in png_pixel_data
Tero Marttila <terom@fixme.fi>
parents: 100
diff changeset
   493
                ADD_AVG(row_buf[out_col * pixel_bytes + 2], c->blue);
56
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   494
            }
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   495
        }
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   496
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   497
        // output
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   498
        png_write_row(img->png, row_buf);
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   499
    }
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   500
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   501
    // done
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   502
    return 0;
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   503
}
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   504
70
35515b3a82b7 more constness for pt_png
Tero Marttila <terom@fixme.fi>
parents: 69
diff changeset
   505
int pt_png_tile (const struct pt_png_header *header, const uint8_t *data, struct pt_tile *tile)
56
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   506
{
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   507
    struct pt_png_img _img, *img = &_img;
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   508
    struct pt_tile_info *ti = &tile->info;
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   509
    int err;
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   510
69
1d188aa94aee pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents: 61
diff changeset
   511
    // init img
84
9cc49917ebac fix pt_png_tile img init
Tero Marttila <terom@fixme.fi>
parents: 70
diff changeset
   512
    memset(img, 0, sizeof(*img));
69
1d188aa94aee pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents: 61
diff changeset
   513
56
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   514
    // check within bounds
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   515
    if (ti->x >= header->width || ti->y >= header->height)
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   516
        // completely outside
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   517
        RETURN_ERROR(PT_ERR_TILE_CLIP);
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   518
    
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   519
    // open PNG writer
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   520
    if ((img->png = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL)) == NULL)
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   521
        JUMP_SET_ERROR(err, PT_ERR_PNG_CREATE);
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   522
    
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   523
    if ((img->info = png_create_info_struct(img->png)) == NULL)
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   524
        JUMP_SET_ERROR(err, PT_ERR_PNG_CREATE);
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   525
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   526
    // libpng error trap
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   527
    if (setjmp(png_jmpbuf(img->png)))
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   528
        JUMP_SET_ERROR(err, PT_ERR_PNG);
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   529
 
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   530
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   531
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   532
    // setup output I/O
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   533
    switch (tile->out_type) {
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   534
        case PT_TILE_OUT_FILE:
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   535
            // use default FILE* operation
69
1d188aa94aee pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents: 61
diff changeset
   536
            // do NOT store in img->fh
56
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   537
            png_init_io(img->png, tile->out.file);
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   538
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   539
            break;
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   540
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   541
        case PT_TILE_OUT_MEM:
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   542
            // use pt_tile_mem struct via pt_png_mem_* callbacks
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   543
            png_set_write_fn(img->png, &tile->out.mem, pt_png_mem_write, pt_png_mem_flush);
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   544
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   545
            break;
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   546
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   547
        default:
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   548
            FATAL("tile->out_type: %d", tile->out_type);
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   549
    }
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   550
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   551
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   552
  
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   553
    // unscaled or scaled?
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   554
    if (ti->zoom)
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   555
        err = pt_png_encode_zoomed(img, header, data, ti);
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   556
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   557
    else
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   558
        err = pt_png_encode_unzoomed(img, header, data, ti);
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   559
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   560
    if (err)
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   561
        goto error;
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   562
    
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   563
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   564
    // flush remaining output
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   565
    png_write_flush(img->png);
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   566
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   567
    // done
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   568
    png_write_end(img->png, img->info);
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   569
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   570
error:
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   571
    // cleanup
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   572
    pt_png_release_write(img);
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   573
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   574
    return err;
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   575
}
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   576
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   577
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   578
void pt_png_release_read (struct pt_png_img *img)
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   579
{
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   580
    png_destroy_read_struct(&img->png, &img->info, NULL);
69
1d188aa94aee pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents: 61
diff changeset
   581
    
1d188aa94aee pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents: 61
diff changeset
   582
    // close possible filehandle
1d188aa94aee pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents: 61
diff changeset
   583
    if (img->fh) {
1d188aa94aee pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents: 61
diff changeset
   584
        if (fclose(img->fh))
1d188aa94aee pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents: 61
diff changeset
   585
            log_warn_errno("fclose");
1d188aa94aee pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents: 61
diff changeset
   586
    }
56
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   587
}
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   588
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   589
void pt_png_release_write (struct pt_png_img *img)
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   590
{
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   591
    png_destroy_write_struct(&img->png, &img->info);
69
1d188aa94aee pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents: 61
diff changeset
   592
1d188aa94aee pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents: 61
diff changeset
   593
    // close possible filehandle
1d188aa94aee pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents: 61
diff changeset
   594
    if (img->fh) {
1d188aa94aee pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents: 61
diff changeset
   595
        if (fclose(img->fh))
1d188aa94aee pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents: 61
diff changeset
   596
            log_warn_errno("fclose");
1d188aa94aee pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents: 61
diff changeset
   597
    }
1d188aa94aee pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents: 61
diff changeset
   598
56
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   599
}
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   600