123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371 |
- #include <stdlib.h>
- #include <stdio.h>
- #include <setjmp.h> /* required for error handling */
- #include "../../png.h"
- #if defined(PNG_READ_SUPPORTED) && defined(PNG_SEQUENTIAL_READ_SUPPORTED)
- static unsigned int
- component(png_const_bytep row, png_uint_32 x, unsigned int c,
- unsigned int bit_depth, unsigned int channels)
- {
-
- png_uint_32 bit_offset_hi = bit_depth * ((x >> 6) * channels);
- png_uint_32 bit_offset_lo = bit_depth * ((x & 0x3f) * channels + c);
- row = (png_const_bytep)(((const png_byte (*)[8])row) + bit_offset_hi);
- row += bit_offset_lo >> 3;
- bit_offset_lo &= 0x07;
-
- switch (bit_depth)
- {
- case 1: return (row[0] >> (7-bit_offset_lo)) & 0x01;
- case 2: return (row[0] >> (6-bit_offset_lo)) & 0x03;
- case 4: return (row[0] >> (4-bit_offset_lo)) & 0x0f;
- case 8: return row[0];
- case 16: return (row[0] << 8) + row[1];
- default:
-
- fprintf(stderr, "pngpixel: invalid bit depth %u\n", bit_depth);
- exit(1);
- }
- }
- static void
- print_pixel(png_structp png_ptr, png_infop info_ptr, png_const_bytep row,
- png_uint_32 x)
- {
- unsigned int bit_depth = png_get_bit_depth(png_ptr, info_ptr);
- switch (png_get_color_type(png_ptr, info_ptr))
- {
- case PNG_COLOR_TYPE_GRAY:
- printf("GRAY %u\n", component(row, x, 0, bit_depth, 1));
- return;
-
- case PNG_COLOR_TYPE_PALETTE:
- {
- int index = component(row, x, 0, bit_depth, 1);
- png_colorp palette = NULL;
- int num_palette = 0;
- if ((png_get_PLTE(png_ptr, info_ptr, &palette, &num_palette) &
- PNG_INFO_PLTE) && num_palette > 0 && palette != NULL)
- {
- png_bytep trans_alpha = NULL;
- int num_trans = 0;
- if ((png_get_tRNS(png_ptr, info_ptr, &trans_alpha, &num_trans,
- NULL) & PNG_INFO_tRNS) && num_trans > 0 &&
- trans_alpha != NULL)
- printf("INDEXED %u = %d %d %d %d\n", index,
- palette[index].red, palette[index].green,
- palette[index].blue,
- index < num_trans ? trans_alpha[index] : 255);
- else
- printf("INDEXED %u = %d %d %d\n", index,
- palette[index].red, palette[index].green,
- palette[index].blue);
- }
- else
- printf("INDEXED %u = invalid index\n", index);
- }
- return;
- case PNG_COLOR_TYPE_RGB:
- printf("RGB %u %u %u\n", component(row, x, 0, bit_depth, 3),
- component(row, x, 1, bit_depth, 3),
- component(row, x, 2, bit_depth, 3));
- return;
- case PNG_COLOR_TYPE_GRAY_ALPHA:
- printf("GRAY+ALPHA %u %u\n", component(row, x, 0, bit_depth, 2),
- component(row, x, 1, bit_depth, 2));
- return;
- case PNG_COLOR_TYPE_RGB_ALPHA:
- printf("RGBA %u %u %u %u\n", component(row, x, 0, bit_depth, 4),
- component(row, x, 1, bit_depth, 4),
- component(row, x, 2, bit_depth, 4),
- component(row, x, 3, bit_depth, 4));
- return;
- default:
- png_error(png_ptr, "pngpixel: invalid color type");
- }
- }
- int main(int argc, const char **argv)
- {
-
- volatile int result = 1;
- if (argc == 4)
- {
- long x = atol(argv[1]);
- long y = atol(argv[2]);
- FILE *f = fopen(argv[3], "rb");
- volatile png_bytep row = NULL;
- if (f != NULL)
- {
-
- png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,
- NULL, NULL, NULL);
- if (png_ptr != NULL)
- {
- png_infop info_ptr = png_create_info_struct(png_ptr);
- if (info_ptr != NULL)
- {
-
-
- if (setjmp(png_jmpbuf(png_ptr)) == 0)
- {
- png_uint_32 width, height;
- int bit_depth, color_type, interlace_method,
- compression_method, filter_method;
- png_bytep row_tmp;
-
- png_init_io(png_ptr, f);
-
- png_read_info(png_ptr, info_ptr);
-
- row = png_malloc(png_ptr, png_get_rowbytes(png_ptr,
- info_ptr));
-
- row_tmp = row;
-
- if (png_get_IHDR(png_ptr, info_ptr, &width, &height,
- &bit_depth, &color_type, &interlace_method,
- &compression_method, &filter_method))
- {
- int passes, pass;
-
- switch (interlace_method)
- {
- case PNG_INTERLACE_NONE:
- passes = 1;
- break;
- case PNG_INTERLACE_ADAM7:
- passes = PNG_INTERLACE_ADAM7_PASSES;
- break;
- default:
- png_error(png_ptr, "pngpixel: unknown interlace");
- }
-
- png_start_read_image(png_ptr);
- for (pass=0; pass<passes; ++pass)
- {
- png_uint_32 ystart, xstart, ystep, xstep;
- png_uint_32 py;
- if (interlace_method == PNG_INTERLACE_ADAM7)
- {
-
- if (PNG_PASS_COLS(width, pass) == 0)
- continue;
-
- xstart = PNG_PASS_START_COL(pass);
- ystart = PNG_PASS_START_ROW(pass);
- xstep = PNG_PASS_COL_OFFSET(pass);
- ystep = PNG_PASS_ROW_OFFSET(pass);
- }
- else
- {
- ystart = xstart = 0;
- ystep = xstep = 1;
- }
-
- for (py = ystart; py < height; py += ystep)
- {
- png_uint_32 px, ppx;
-
- png_read_row(png_ptr, row_tmp, NULL);
-
- if (y == py) for (px = xstart, ppx = 0;
- px < width; px += xstep, ++ppx) if (x == px)
- {
-
- print_pixel(png_ptr, info_ptr, row_tmp, ppx);
-
- goto pass_loop_end;
- }
- }
- }
-
- pass_loop_end:
- row = NULL;
- png_free(png_ptr, row_tmp);
- }
- else
- png_error(png_ptr, "pngpixel: png_get_IHDR failed");
- }
- else
- {
-
- if (row != NULL)
- {
-
- png_bytep row_tmp = row;
- row = NULL;
- png_free(png_ptr, row_tmp);
- }
- }
- png_destroy_info_struct(png_ptr, &info_ptr);
- }
- else
- fprintf(stderr, "pngpixel: out of memory allocating png_info\n");
- png_destroy_read_struct(&png_ptr, NULL, NULL);
- }
- else
- fprintf(stderr, "pngpixel: out of memory allocating png_struct\n");
- }
- else
- fprintf(stderr, "pngpixel: %s: could not open file\n", argv[3]);
- }
- else
-
- fprintf(stderr, "pngpixel: usage: pngpixel x y png-file\n");
- return result;
- }
- #endif
|