438 * Write scaled tile data |
438 * Write scaled tile data |
439 */ |
439 */ |
440 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) |
440 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) |
441 { |
441 { |
442 // size of the image data in px |
442 // size of the image data in px |
443 size_t data_width = scale_by_zoom_factor(ti->width, -ti->zoom); |
443 size_t data_width = scale_by_zoom_factor(ti->width, ti->zoom); |
444 size_t data_height = scale_by_zoom_factor(ti->height, -ti->zoom); |
444 size_t data_height = scale_by_zoom_factor(ti->height, ti->zoom); |
445 |
445 |
446 // input pixels per output pixel |
446 // input pixels per output pixel |
447 size_t pixel_size = scale_by_zoom_factor(1, -ti->zoom); |
447 size_t pixel_size = scale_by_zoom_factor(1, ti->zoom); |
448 |
448 |
449 // bytes per output pixel |
449 // bytes per output pixel |
450 size_t pixel_bytes = 3; |
450 size_t pixel_bytes = 3; |
451 |
451 |
452 // size of the output tile in px |
452 // size of the output tile in px |
460 |
460 |
461 // color entry for pixel |
461 // color entry for pixel |
462 const png_color *c = &header->palette[0]; |
462 const png_color *c = &header->palette[0]; |
463 |
463 |
464 // only supports zooming out... |
464 // only supports zooming out... |
465 if (ti->zoom >= 0) |
465 if (ti->zoom < 0) |
466 RETURN_ERROR(PT_ERR_TILE_ZOOM); |
466 RETURN_ERROR(PT_ERR_TILE_ZOOM); |
467 |
467 |
468 if ((row_buf = malloc(row_bytes)) == NULL) |
468 if ((row_buf = malloc(row_bytes)) == NULL) |
469 RETURN_ERROR(PT_ERR_MEM); |
469 RETURN_ERROR(PT_ERR_MEM); |
470 |
470 |
482 // ...each output row |
482 // ...each output row |
483 for (size_t out_row = 0; out_row < ti->height; out_row++) { |
483 for (size_t out_row = 0; out_row < ti->height; out_row++) { |
484 memset(row_buf, 0, row_bytes); |
484 memset(row_buf, 0, row_bytes); |
485 |
485 |
486 // ...includes pixels starting from this row. |
486 // ...includes pixels starting from this row. |
487 size_t in_row_offset = ti->y + scale_by_zoom_factor(out_row, -ti->zoom); |
487 size_t in_row_offset = ti->y + scale_by_zoom_factor(out_row, ti->zoom); |
488 |
488 |
489 // ...each out row includes pixel_size in rows |
489 // ...each out row includes pixel_size in rows |
490 for (size_t in_row = in_row_offset; in_row < in_row_offset + pixel_size && in_row < header->height; in_row++) { |
490 for (size_t in_row = in_row_offset; in_row < in_row_offset + pixel_size && in_row < header->height; in_row++) { |
491 // and includes each input pixel |
491 // and includes each input pixel |
492 for (size_t in_col = ti->x; in_col < ti->x + data_width && in_col < header->width; in_col++) { |
492 for (size_t in_col = ti->x; in_col < ti->x + data_width && in_col < header->width; in_col++) { |
493 |
493 |
494 // ...for this output pixel |
494 // ...for this output pixel |
495 size_t out_col = scale_by_zoom_factor(in_col - ti->x, ti->zoom); |
495 size_t out_col = scale_by_zoom_factor(in_col - ti->x, -ti->zoom); |
496 |
496 |
497 // get pixel RGB data |
497 // get pixel RGB data |
498 png_pixel_data(&c, header, data, in_row, in_col); |
498 png_pixel_data(&c, header, data, in_row, in_col); |
499 |
499 |
500 // average the RGB data |
500 // average the RGB data |