/*based on the https://github.com/gbenison/png-text-embedwith small modificationsgcc png-text-dump.c -L/usr/local/lib -lpng -o png-text-dump // with png library./png-text-dump r.png*/#include<stdio.h>#include<png.h> // libpng intmain(intargc,char*argv[]){FILE*infile=stdin;if(argc>1)infile=fopen(argv[1],"r");if(infile==NULL){fprintf(stderr,"Could not open %s\n",argv[1]);return1;}fprintf(stdout,"File %s opened with libpng version %s\n",argv[1],PNG_LIBPNG_VER_STRING);/* allocate png structures */png_structpread_ptr=png_create_read_struct(PNG_LIBPNG_VER_STRING,NULL,NULL,NULL);png_infopread_info_ptr=png_create_info_struct(read_ptr);png_infopend_info_ptr=png_create_info_struct(read_ptr);png_init_io(read_ptr,infile);png_read_png(read_ptr,read_info_ptr,0,NULL);png_textptext_ptr;intnum_text;png_get_text(read_ptr,read_info_ptr,&text_ptr,&num_text);/* echo text contents. */inti;for(i=0;i<num_text;++i){printf("==== text chunk %d: \"%s\" = tEXt%s ====\n",i+1,text_ptr[i].key,text_ptr[i].key);printf("%s\n\n",text_ptr[i].text);}return0;}
Wczytamy plik z commons:
plik z opisem
./png-text-dump r.png
i otrzymamy:
File r.png opened with libpng version 1.2.50
==== text chunk 1: "Title"=tEXtTitle====
RGBA Logo==== text chunk 2: "Author"=tEXtAuthor====
Shlomi Tal==== text chunk 3: "Description"=tEXtDescription====
Image demonstrating the use of an alpha channel for anti-aliasing of transparency and fortranslucency==== text chunk 4: "Comment"=tEXtComment====
This is the large version, with a dot size of 100 micrometres (254 DPI), yielding 15 cm for both width and height==== text chunk 5: "Comment"=tEXtComment====
Colours are from the Gretag-Macbeth palette==== text chunk 6: "Copyright"=tEXtCopyright====
Creative Commons Attribution-ShareAlike 3.0 and older==== text chunk 7: "Software"=tEXtSoftware====
GIMP 2.2.10
==== text chunk 8: "Creation Time"= tEXtCreation Time====
Tue 18 Mar 200816:03 +0200
/*I'm trying to write (using libpng) an 16-bit grayscale image where each point color equals to sum of its coordinates. The following code should produce a 16-bit PNG, but instead produces 8-bit like this. Why?https://stackoverflow.com/questions/8818206/16-bit-grayscale-pnggcc p.c -L/usr/local/lib -lpng -Wall -Wextra*/#include<stdio.h>#include<stdlib.h>#include<stdint.h>#include<png.h>// libpng voidsave_png(FILE*fp,longintsize){png_structppng_ptr=NULL;png_infopinfo_ptr=NULL;intx,y;png_bytepprow_pointers;intiMax=(int)size;intyMax=(int)size;png_ptr=png_create_write_struct(PNG_LIBPNG_VER_STRING,NULL,NULL,NULL);if(png_ptr==NULL){return;}info_ptr=png_create_info_struct(png_ptr);if(info_ptr==NULL){png_destroy_write_struct(&png_ptr,NULL);return;}if(setjmp(png_jmpbuf(png_ptr))){png_destroy_write_struct(&png_ptr,&info_ptr);return;}png_set_IHDR(png_ptr,info_ptr,size,size,// width and height16,// bit depthPNG_COLOR_TYPE_GRAY,// color typePNG_INTERLACE_NONE,PNG_COMPRESSION_TYPE_DEFAULT,PNG_FILTER_TYPE_DEFAULT);/* Initialize rows of PNG. */row_pointers=(png_bytepp)png_malloc(png_ptr,size*sizeof(png_bytep));for(inti=0;i<iMax;i++)row_pointers[i]=NULL;for(inti=0;i<iMax;i++)row_pointers[i]=png_malloc(png_ptr,size*2);//set row datafor(y=0;y<yMax;++y){png_byteprow=row_pointers[y];for(x=0;x<iMax;++x){shortcolor=x+y;*row++=(png_byte)(color&0xFF);*row++=(png_byte)(color>>8);}}/* Actually write the image data. */png_init_io(png_ptr,fp);png_set_rows(png_ptr,info_ptr,row_pointers);png_write_png(png_ptr,info_ptr,PNG_TRANSFORM_IDENTITY,NULL);//png_write_image(png_ptr, row_pointers);/* Cleanup. */for(y=0;y<yMax;y++){png_free(png_ptr,row_pointers[y]);}png_free(png_ptr,row_pointers);png_destroy_write_struct(&png_ptr,&info_ptr);}intmain(){FILE*f;if((f=fopen("PNG16g.png","wb"))!=NULL){save_png(f,1000);fclose(f);}return0;}
Sprawdzamy plik
pngcheck -cvt ./PNG16g.png
Wynik
File: ./PNG16g.png (12449 bytes)
chunk IHDR at offset 0x0000c, length 13
1000 x 1000 image, 16-bit grayscale, non-interlaced
chunk IDAT at offset 0x00025, length 8192
zlib: deflated, 32K window, default compression
chunk IDAT at offset 0x02031, length 4188
chunk IEND at offset 0x03099, length 0
No errors detected in ./PNG16g.png (4 chunks, 99.4% compression).