| 1 | #include <stdio.h> |
|---|
| 2 | #include <stdlib.h> |
|---|
| 3 | #include <string.h> |
|---|
| 4 | #include <png.h> |
|---|
| 5 | #include "proto.h" |
|---|
| 6 | |
|---|
| 7 | #ifdef __64BIT__ |
|---|
| 8 | typedef int g2int; |
|---|
| 9 | #else |
|---|
| 10 | typedef long g2int; |
|---|
| 11 | #endif |
|---|
| 12 | |
|---|
| 13 | struct png_stream { |
|---|
| 14 | unsigned char *stream_ptr; /* location to write PNG stream */ |
|---|
| 15 | g2int stream_len; /* number of bytes written */ |
|---|
| 16 | }; |
|---|
| 17 | typedef struct png_stream png_stream; |
|---|
| 18 | |
|---|
| 19 | void user_read_data(png_structp , png_bytep , png_uint_32 ); |
|---|
| 20 | |
|---|
| 21 | void user_read_data(png_structp png_ptr,png_bytep data, png_uint_32 length) |
|---|
| 22 | /* |
|---|
| 23 | Custom read function used so that libpng will read a PNG stream |
|---|
| 24 | from memory instead of a file on disk. |
|---|
| 25 | */ |
|---|
| 26 | { |
|---|
| 27 | char *ptr; |
|---|
| 28 | g2int offset; |
|---|
| 29 | png_stream *mem; |
|---|
| 30 | |
|---|
| 31 | mem=(png_stream *)png_get_io_ptr(png_ptr); |
|---|
| 32 | ptr=(void *)mem->stream_ptr; |
|---|
| 33 | offset=mem->stream_len; |
|---|
| 34 | /* printf("SAGrd %ld %ld %x\n",offset,length,ptr); */ |
|---|
| 35 | memcpy(data,ptr+offset,length); |
|---|
| 36 | mem->stream_len += length; |
|---|
| 37 | } |
|---|
| 38 | |
|---|
| 39 | |
|---|
| 40 | |
|---|
| 41 | int DEC_PNG(unsigned char *pngbuf,g2int *width,g2int *height,char *cout) |
|---|
| 42 | { |
|---|
| 43 | int interlace,color,compres,filter,bit_depth; |
|---|
| 44 | g2int j,k,n,bytes,clen; |
|---|
| 45 | png_structp png_ptr; |
|---|
| 46 | png_infop info_ptr,end_info; |
|---|
| 47 | png_bytepp row_pointers; |
|---|
| 48 | png_stream read_io_ptr; |
|---|
| 49 | |
|---|
| 50 | /* check if stream is a valid PNG format */ |
|---|
| 51 | |
|---|
| 52 | if ( png_sig_cmp(pngbuf,0,8) != 0) |
|---|
| 53 | return (-3); |
|---|
| 54 | |
|---|
| 55 | /* create and initialize png_structs */ |
|---|
| 56 | |
|---|
| 57 | png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, (png_voidp)NULL, |
|---|
| 58 | NULL, NULL); |
|---|
| 59 | if (!png_ptr) |
|---|
| 60 | return (-1); |
|---|
| 61 | |
|---|
| 62 | info_ptr = png_create_info_struct(png_ptr); |
|---|
| 63 | if (!info_ptr) |
|---|
| 64 | { |
|---|
| 65 | png_destroy_read_struct(&png_ptr,(png_infopp)NULL,(png_infopp)NULL); |
|---|
| 66 | return (-2); |
|---|
| 67 | } |
|---|
| 68 | |
|---|
| 69 | end_info = png_create_info_struct(png_ptr); |
|---|
| 70 | if (!end_info) |
|---|
| 71 | { |
|---|
| 72 | png_destroy_read_struct(&png_ptr,(png_infopp)info_ptr,(png_infopp)NULL); |
|---|
| 73 | return (-2); |
|---|
| 74 | } |
|---|
| 75 | |
|---|
| 76 | /* Set Error callback */ |
|---|
| 77 | |
|---|
| 78 | if (setjmp(png_jmpbuf(png_ptr))) |
|---|
| 79 | { |
|---|
| 80 | png_destroy_read_struct(&png_ptr, &info_ptr,&end_info); |
|---|
| 81 | return (-3); |
|---|
| 82 | } |
|---|
| 83 | |
|---|
| 84 | /* Initialize info for reading PNG stream from memory */ |
|---|
| 85 | |
|---|
| 86 | read_io_ptr.stream_ptr=(png_voidp)pngbuf; |
|---|
| 87 | read_io_ptr.stream_len=0; |
|---|
| 88 | |
|---|
| 89 | /* Set new custom read function */ |
|---|
| 90 | |
|---|
| 91 | png_set_read_fn(png_ptr,(voidp)&read_io_ptr,(png_rw_ptr)user_read_data); |
|---|
| 92 | /* png_init_io(png_ptr, fptr); */ |
|---|
| 93 | |
|---|
| 94 | /* Read and decode PNG stream */ |
|---|
| 95 | |
|---|
| 96 | png_read_png(png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, NULL); |
|---|
| 97 | |
|---|
| 98 | /* Get pointer to each row of image data */ |
|---|
| 99 | |
|---|
| 100 | row_pointers = png_get_rows(png_ptr, info_ptr); |
|---|
| 101 | |
|---|
| 102 | /* Get image info, such as size, depth, colortype, etc... */ |
|---|
| 103 | |
|---|
| 104 | /*printf("SAGT:png %d %d %d\n",info_ptr->width,info_ptr->height,info_ptr->bit_depth);*/ |
|---|
| 105 | (void)png_get_IHDR(png_ptr, info_ptr, (png_uint_32 *)width, (png_uint_32 *)height, |
|---|
| 106 | &bit_depth, &color, &interlace, &compres, &filter); |
|---|
| 107 | |
|---|
| 108 | /* Check if image was grayscale */ |
|---|
| 109 | |
|---|
| 110 | /* |
|---|
| 111 | if (color != PNG_COLOR_TYPE_GRAY ) { |
|---|
| 112 | fprintf(stderr,"dec_png: Grayscale image was expected. \n"); |
|---|
| 113 | } |
|---|
| 114 | */ |
|---|
| 115 | if ( color == PNG_COLOR_TYPE_RGB ) { |
|---|
| 116 | bit_depth=24; |
|---|
| 117 | } |
|---|
| 118 | else if ( color == PNG_COLOR_TYPE_RGB_ALPHA ) { |
|---|
| 119 | bit_depth=32; |
|---|
| 120 | } |
|---|
| 121 | /* Copy image data to output string */ |
|---|
| 122 | |
|---|
| 123 | n=0; |
|---|
| 124 | bytes=bit_depth/8; |
|---|
| 125 | clen=(*width)*bytes; |
|---|
| 126 | for (j=0;j<*height;j++) { |
|---|
| 127 | for (k=0;k<clen;k++) { |
|---|
| 128 | cout[n]=*(row_pointers[j]+k); |
|---|
| 129 | n++; |
|---|
| 130 | } |
|---|
| 131 | } |
|---|
| 132 | |
|---|
| 133 | /* Clean up */ |
|---|
| 134 | |
|---|
| 135 | png_destroy_read_struct(&png_ptr, &info_ptr, &end_info); |
|---|
| 136 | return 0; |
|---|
| 137 | |
|---|
| 138 | } |
|---|
| 139 | |
|---|