png.c 6.3 KB
Newer Older
G
Guy Schalnat 已提交
1 2 3

/* png.c - location for general purpose png functions

G
Guy Schalnat 已提交
4
   libpng 1.0 beta 3 - version 0.89
G
Guy Schalnat 已提交
5
   For conditions of distribution and use, see copyright notice in png.h
G
Guy Schalnat 已提交
6
   Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
G
Guy Schalnat 已提交
7
   May 25, 1996
G
Guy Schalnat 已提交
8 9 10 11 12 13
   */

#define PNG_INTERNAL
#define PNG_NO_EXTERN
#include "png.h"

G
Guy Schalnat 已提交
14 15
/* version information for c files.  This better match the version
   string defined in png.h */
G
Guy Schalnat 已提交
16
char png_libpng_ver[] = "0.89";
G
Guy Schalnat 已提交
17

G
Guy Schalnat 已提交
18
/* place to hold the signiture string for a png file. */
G
Guy Schalnat 已提交
19
png_byte FARDATA png_sig[8] = {137, 80, 78, 71, 13, 10, 26, 10};
G
Guy Schalnat 已提交
20 21 22 23

/* constant strings for known chunk types.  If you need to add a chunk,
   add a string holding the name here.  If you want to make the code
   portable to EBCDIC machines, use ASCII numbers, not characters. */
G
Guy Schalnat 已提交
24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
png_byte FARDATA png_IHDR[4] = { 73,  72,  68,  82};
png_byte FARDATA png_IDAT[4] = { 73,  68,  65,  84};
png_byte FARDATA png_IEND[4] = { 73,  69,  78,  68};
png_byte FARDATA png_PLTE[4] = { 80,  76,  84,  69};
png_byte FARDATA png_gAMA[4] = {103,  65,  77,  65};
png_byte FARDATA png_sBIT[4] = {115,  66,  73,  84};
png_byte FARDATA png_cHRM[4] = { 99,  72,  82,  77};
png_byte FARDATA png_tRNS[4] = {116,  82,  78,  83};
png_byte FARDATA png_bKGD[4] = { 98,  75,  71,  68};
png_byte FARDATA png_hIST[4] = {104,  73,  83,  84};
png_byte FARDATA png_tEXt[4] = {116,  69,  88, 116};
png_byte FARDATA png_zTXt[4] = {122,  84,  88, 116};
png_byte FARDATA png_pHYs[4] = {112,  72,  89, 115};
png_byte FARDATA png_oFFs[4] = {111,  70,  70, 115};
png_byte FARDATA png_tIME[4] = {116,  73,  77,  69};
G
Guy Schalnat 已提交
39 40 41 42

/* arrays to facilitate easy interlacing - use pass (0 - 6) as index */

/* start of interlace block */
G
Guy Schalnat 已提交
43
int FARDATA png_pass_start[] = {0, 4, 0, 2, 0, 1, 0};
G
Guy Schalnat 已提交
44 45

/* offset to next interlace block */
G
Guy Schalnat 已提交
46
int FARDATA png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1};
G
Guy Schalnat 已提交
47 48

/* start of interlace block in the y direction */
G
Guy Schalnat 已提交
49
int FARDATA png_pass_ystart[] = {0, 0, 4, 0, 2, 0, 1};
G
Guy Schalnat 已提交
50 51

/* offset to next interlace block in the y direction */
G
Guy Schalnat 已提交
52
int FARDATA png_pass_yinc[] = {8, 8, 8, 4, 4, 2, 2};
G
Guy Schalnat 已提交
53 54 55 56

/* width of interlace block */
/* this is not currently used - if you need it, uncomment it here and
   in png.h
G
Guy Schalnat 已提交
57
int FARDATA png_pass_width[] = {8, 4, 4, 2, 2, 1, 1};
G
Guy Schalnat 已提交
58 59 60 61 62
*/

/* height of interlace block */
/* this is not currently used - if you need it, uncomment it here and
   in png.h
G
Guy Schalnat 已提交
63
int FARDATA png_pass_height[] = {8, 8, 4, 4, 2, 2, 1};
G
Guy Schalnat 已提交
64 65 66
*/

/* mask to determine which pixels are valid in a pass */
G
Guy Schalnat 已提交
67
int FARDATA png_pass_mask[] = {0x80, 0x08, 0x88, 0x22, 0xaa, 0x55, 0xff};
G
Guy Schalnat 已提交
68 69

/* mask to determine which pixels to overwrite while displaying */
G
Guy Schalnat 已提交
70
int FARDATA png_pass_dsp_mask[] = {0xff, 0x0f, 0xff, 0x33, 0xff, 0x55, 0xff};
G
Guy Schalnat 已提交
71 72 73


int
G
Guy Schalnat 已提交
74
png_check_sig(png_bytep sig, int num)
G
Guy Schalnat 已提交
75
{
G
Guy Schalnat 已提交
76
   if (num > 8)
G
Guy Schalnat 已提交
77 78 79 80
      num = 8;
   if (num < 1)
      return 0;

G
Guy Schalnat 已提交
81
   return (!png_memcmp(sig, png_sig, num));
G
Guy Schalnat 已提交
82 83 84
}

/* Function to allocate memory for zlib. */
G
Guy Schalnat 已提交
85 86
voidpf
png_zalloc(voidpf png_ptr, uInt items, uInt size)
G
Guy Schalnat 已提交
87
{
G
Guy Schalnat 已提交
88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103
   png_voidp ptr;
   png_uint_32 num_bytes;

   ptr = png_large_malloc((png_structp)png_ptr,
      (png_uint_32)items * (png_uint_32)size);
   num_bytes = (png_uint_32)items * (png_uint_32)size;
   if (num_bytes > (png_uint_32)0x7fff)
   {
      png_memset(ptr, 0, (png_size_t)0x8000L);
      png_memset((png_bytep)ptr + (png_size_t)0x8000L, 0,
         (png_size_t)(num_bytes - (png_uint_32)0x8000L));
   }
   else
   {
      png_memset(ptr, 0, (png_size_t)num_bytes);
   }
G
Guy Schalnat 已提交
104
   return (voidpf)(ptr);
G
Guy Schalnat 已提交
105 106 107 108
}

/* function to free memory for zlib */
void
G
Guy Schalnat 已提交
109
png_zfree(voidpf png_ptr, voidpf ptr)
G
Guy Schalnat 已提交
110
{
G
Guy Schalnat 已提交
111
   png_large_free((png_structp)png_ptr, (png_voidp)ptr);
G
Guy Schalnat 已提交
112 113 114 115 116
}

/* reset the crc variable to 32 bits of 1's.  Care must be taken
   in case crc is > 32 bits to leave the top bits 0 */
void
G
Guy Schalnat 已提交
117
png_reset_crc(png_structp png_ptr)
G
Guy Schalnat 已提交
118 119 120 121 122 123
{
   /* set crc to all 1's */
   png_ptr->crc = 0xffffffffL;
}

/* Note: the crc code below was copied from the sample code in the
G
Guy Schalnat 已提交
124 125
   PNG spec, with appropriate modifications made to ensure the
   variables are large enough */
G
Guy Schalnat 已提交
126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156

/* table of crc's of all 8-bit messages.  If you wish to png_malloc this
   table, turn this into a pointer, and png_malloc it in make_crc_table().
   You may then want to hook it into png_struct and free it with the
   destroy functions. */
static png_uint_32 crc_table[256];

/* Flag: has the table been computed? Initially false. */
static int crc_table_computed = 0;

/* make the table for a fast crc */
static void
make_crc_table(void)
{
  png_uint_32 c;
  int n, k;

  for (n = 0; n < 256; n++)
  {
   c = (png_uint_32)n;
   for (k = 0; k < 8; k++)
     c = c & 1 ? 0xedb88320L ^ (c >> 1) : c >> 1;
   crc_table[n] = c;
  }
  crc_table_computed = 1;
}

/* update a running crc with the bytes buf[0..len-1]--the crc should be
   initialized to all 1's, and the transmitted value is the 1's complement
   of the final running crc. */
static png_uint_32
G
Guy Schalnat 已提交
157
update_crc(png_uint_32 crc, png_bytep buf, png_uint_32 len)
G
Guy Schalnat 已提交
158 159
{
  png_uint_32 c;
G
Guy Schalnat 已提交
160
  png_bytep p;
G
Guy Schalnat 已提交
161 162 163 164 165 166 167 168 169 170 171 172 173
  png_uint_32 n;

  c = crc;
  p = buf;
  n = len;

  if (!crc_table_computed)
  {
   make_crc_table();
  }

  if (n > 0) do
  {
G
Guy Schalnat 已提交
174
   c = crc_table[(png_byte)((c ^ (*p++)) & 0xff)] ^ (c >> 8);
G
Guy Schalnat 已提交
175 176 177 178 179 180 181 182 183 184
  } while (--n);

  return c;
}

/* calculate the crc over a section of data.  Note that while we
   are passing in a 32 bit value for length, on 16 bit machines, you
   would need to use huge pointers to access all that data.  If you
   need this, put huge here and above. */
void
G
Guy Schalnat 已提交
185
png_calculate_crc(png_structp png_ptr, png_bytep ptr,
G
Guy Schalnat 已提交
186 187 188 189
   png_uint_32 length)
{
   png_ptr->crc = update_crc(png_ptr->crc, ptr, length);
}
G
Guy Schalnat 已提交
190 191 192 193 194 195 196 197 198 199 200 201 202 203 204

png_infop
png_create_info_struct(png_structp png_ptr)
{
   png_infop info_ptr;

   if ((info_ptr = (png_infop)png_create_struct(PNG_STRUCT_INFO)) != NULL)
   {
      png_memset(info_ptr, 0, sizeof(png_info));
      png_ptr->do_free |= PNG_FREE_INFO;
   }

   return info_ptr;
}

G
Guy Schalnat 已提交
205
void
G
Guy Schalnat 已提交
206
png_info_init(png_infop info)
G
Guy Schalnat 已提交
207 208
{
   /* set everything to 0 */
G
Guy Schalnat 已提交
209
   png_memset(info, 0, sizeof (png_info));
G
Guy Schalnat 已提交
210
}
G
Guy Schalnat 已提交
211

G
Guy Schalnat 已提交
212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228
/* This function returns a pointer to the io_ptr associated with the user
   functions.  The application should free any memory associated with this
   pointer before png_write_destroy and png_read_destroy are called. */
png_voidp
png_get_io_ptr(png_structp png_ptr)
{
   return png_ptr->io_ptr;
}
 
/* Initialize the default input/output functions for the png file.  If you
   change the read, or write routines, you can call either png_set_read_fn()
   or png_set_write_fn() instead of png_init_io(). */
void
png_init_io(png_structp png_ptr, FILE *fp)
{
   png_ptr->io_ptr = (png_voidp)fp;
}