src/lib/png.c
author Tero Marttila <terom@fixme.fi>
Mon, 25 Jan 2010 04:29:25 +0200
changeset 84 9cc49917ebac
parent 70 35515b3a82b7
child 86 d4a62899587f
permissions -rw-r--r--
fix pt_png_tile img init
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
31650ef395d3 use pt_png_decode_direct if no background color is set..
Tero Marttila <terom@fixme.fi>
parents: 56
diff changeset
   220
    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
   221
        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
   222
31650ef395d3 use pt_png_decode_direct if no background color is set..
Tero Marttila <terom@fixme.fi>
parents: 56
diff changeset
   223
    else
31650ef395d3 use pt_png_decode_direct if no background color is set..
Tero Marttila <terom@fixme.fi>
parents: 56
diff changeset
   224
        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
   225
    
31650ef395d3 use pt_png_decode_direct if no background color is set..
Tero Marttila <terom@fixme.fi>
parents: 56
diff changeset
   226
    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
   227
        return err;
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   228
    
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   229
    // 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
   230
    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
   231
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   232
    return 0;
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   233
}
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
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
   236
{
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   237
    // 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
   238
    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
   239
    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
   240
    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
   241
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   242
    return 0;
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   243
}
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
 * 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
   247
 */
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   248
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
   249
{
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   250
    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
   251
    int err;
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   252
    
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   253
    // 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
   254
    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
   255
        // 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
   256
        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
   257
}
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
 * 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
   261
 */
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   262
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
   263
{
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   264
    // no-op
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   265
}
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
 * 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
   270
 */
70
35515b3a82b7 more constness for pt_png
Tero Marttila <terom@fixme.fi>
parents: 69
diff changeset
   271
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
   272
{
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   273
    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
   274
}
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
 * Fill in a clipped region of \a width_px pixels at the given row segment
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   278
 */
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   279
static inline void tile_row_fill_clip (const struct pt_png_header *header, png_byte *row, size_t width_px)
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   280
{
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   281
    // XXX: use a configureable background color, or full transparency?
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   282
    memset(row, /* 0xd7 */ 0x00, width_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
   283
}
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   284
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   285
/**
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   286
 * 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
   287
 */
70
35515b3a82b7 more constness for pt_png
Tero Marttila <terom@fixme.fi>
parents: 69
diff changeset
   288
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
   289
{
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   290
    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
   291
        // write data directly
70
35515b3a82b7 more constness for pt_png
Tero Marttila <terom@fixme.fi>
parents: 69
diff changeset
   292
        // missing const...
35515b3a82b7 more constness for pt_png
Tero Marttila <terom@fixme.fi>
parents: 69
diff changeset
   293
        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
   294
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   295
    return 0;
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   296
}
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   297
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   298
/**
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   299
 * 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
   300
 */
70
35515b3a82b7 more constness for pt_png
Tero Marttila <terom@fixme.fi>
parents: 69
diff changeset
   301
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
   302
{
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   303
    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
   304
    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
   305
    
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   306
    // 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
   307
    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
   308
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   309
69
1d188aa94aee pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents: 61
diff changeset
   310
    // 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
   311
    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
   312
    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
   313
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
    // 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
   316
    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
   317
        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
   318
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   319
    // 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
   320
    // 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
   321
    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
   322
    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
   323
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   324
    // 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
   325
    // 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
   326
    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
   327
        // 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
   328
        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
   329
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   330
        // 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
   331
        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
   332
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   333
        // write
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   334
        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
   335
    }
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
    // 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
   338
    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
   339
    
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   340
    // 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
   341
    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
   342
        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
   343
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   344
    // ok
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   345
    return 0;
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   346
}
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
static size_t scale_by_zoom_factor (size_t value, int z)
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
    if (z > 0)
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   351
        return value << z;
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   352
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   353
    else if (z < 0)
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   354
        return value >> -z;
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
    else
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   357
        return value;
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   358
}
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
#define ADD_AVG(l, r) (l) = ((l) + (r)) / 2
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   361
70
35515b3a82b7 more constness for pt_png
Tero Marttila <terom@fixme.fi>
parents: 69
diff changeset
   362
static int png_pixel_data (png_color *out, 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
   363
{
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   364
    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
   365
        // palette entry number
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   366
        int p;
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   367
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   368
        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
   369
            p = *((uint8_t *) tile_row_col(header, data, row, col));
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   370
        else
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   371
            return -1;
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   372
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   373
        if (p >= header->num_palette)
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   374
            return -1;
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   375
        
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   376
        // reference data from palette
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   377
        *out = header->palette[p];
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   378
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   379
        return 0;
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
    } else {
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   382
        return -1;
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
}
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   385
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   386
/**
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   387
 * 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
   388
 */
70
35515b3a82b7 more constness for pt_png
Tero Marttila <terom@fixme.fi>
parents: 69
diff changeset
   389
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
   390
{
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   391
    int err;
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   392
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   393
    // 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
   394
    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
   395
            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
   396
    );
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   397
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   398
    // set palette?
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   399
    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
   400
        // oops... missing const
31650ef395d3 use pt_png_decode_direct if no background color is set..
Tero Marttila <terom@fixme.fi>
parents: 56
diff changeset
   401
        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
   402
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   403
    // 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
   404
    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
   405
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   406
    // 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
   407
    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
   408
    
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   409
    // 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
   410
    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
   411
        // 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
   412
        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
   413
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   414
    else
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   415
        // 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
   416
        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
   417
    
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   418
    return err;
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   419
}
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   420
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   421
/**
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   422
 * 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
   423
 */
70
35515b3a82b7 more constness for pt_png
Tero Marttila <terom@fixme.fi>
parents: 69
diff changeset
   424
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
   425
{
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   426
    // 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
   427
    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
   428
    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
   429
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   430
    // 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
   431
    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
   432
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   433
    // 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
   434
    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
   435
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   436
    // 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
   437
    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
   438
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   439
    // 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
   440
    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
   441
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   442
    // 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
   443
    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
   444
    
69
1d188aa94aee pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents: 61
diff changeset
   445
    // 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
   446
    if (ti->zoom >= 0)
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   447
        RETURN_ERROR(PT_ERR_ZOOM);
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   448
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   449
    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
   450
        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
   451
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   452
    // suppress warning...
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   453
    (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
   454
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   455
    // 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
   456
    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
   457
            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
   458
    );
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   459
    
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   460
    // 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
   461
    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
   462
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   463
    // ...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
   464
    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
   465
        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
   466
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   467
        // ...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
   468
        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
   469
        
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   470
        // ...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
   471
        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
   472
            // 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
   473
            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
   474
                png_color c;
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
                // ...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
   477
                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
   478
                
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   479
                // get pixel RGB data
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   480
                if (png_pixel_data(&c, header, data, in_row, in_col))
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   481
                    return -1;
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   482
                
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   483
                // average the RGB data        
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   484
                ADD_AVG(row_buf[out_col * pixel_bytes + 0], c.red);
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   485
                ADD_AVG(row_buf[out_col * pixel_bytes + 1], c.green);
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   486
                ADD_AVG(row_buf[out_col * pixel_bytes + 2], c.blue);
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   487
            }
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   488
        }
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
        // output
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   491
        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
   492
    }
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   493
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   494
    // done
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   495
    return 0;
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
70
35515b3a82b7 more constness for pt_png
Tero Marttila <terom@fixme.fi>
parents: 69
diff changeset
   498
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
   499
{
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   500
    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
   501
    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
   502
    int err;
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   503
69
1d188aa94aee pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents: 61
diff changeset
   504
    // init img
84
9cc49917ebac fix pt_png_tile img init
Tero Marttila <terom@fixme.fi>
parents: 70
diff changeset
   505
    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
   506
56
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   507
    // 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
   508
    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
   509
        // completely outside
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   510
        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
   511
    
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   512
    // 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
   513
    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
   514
        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
   515
    
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   516
    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
   517
        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
   518
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   519
    // 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
   520
    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
   521
        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
   522
 
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   523
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   524
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   525
    // 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
   526
    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
   527
        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
   528
            // use default FILE* operation
69
1d188aa94aee pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents: 61
diff changeset
   529
            // 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
   530
            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
   531
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   532
            break;
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   533
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_MEM:
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   535
            // 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
   536
            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
   537
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   538
            break;
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   539
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   540
        default:
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   541
            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
   542
    }
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   543
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
  
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   546
    // 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
   547
    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
   548
        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
   549
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   550
    else
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   551
        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
   552
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   553
    if (err)
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   554
        goto error;
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   555
    
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
    // 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
   558
    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
   559
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   560
    // done
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   561
    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
   562
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   563
error:
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   564
    // cleanup
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   565
    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
   566
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   567
    return err;
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   568
}
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
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   571
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   572
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
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
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   579
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
   580
{
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   581
    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
   582
    
1d188aa94aee pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents: 61
diff changeset
   583
    // close possible filehandle
1d188aa94aee pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents: 61
diff changeset
   584
    if (img->fh) {
1d188aa94aee pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents: 61
diff changeset
   585
        if (fclose(img->fh))
1d188aa94aee pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents: 61
diff changeset
   586
            log_warn_errno("fclose");
1d188aa94aee pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents: 61
diff changeset
   587
    }
56
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
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   590
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
   591
{
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   592
    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
   593
1d188aa94aee pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents: 61
diff changeset
   594
    // close possible filehandle
1d188aa94aee pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents: 61
diff changeset
   595
    if (img->fh) {
1d188aa94aee pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents: 61
diff changeset
   596
        if (fclose(img->fh))
1d188aa94aee pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents: 61
diff changeset
   597
            log_warn_errno("fclose");
1d188aa94aee pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents: 61
diff changeset
   598
    }
1d188aa94aee pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents: 61
diff changeset
   599
56
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   600
}
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   601