download imgpng.c
Language: C
Copyright: (c) 1998
LOC: 232
Project Info
BeKaffe
Server: SourceForge
Type: cvs
...fe\libraries\clib\awt\BeOS\
   cbd.c
   clr.c
   evt.c
   fnt.c
   gra.c
   graphics.c
   graphics.h
   img.c
   imggif.c
   imgjpeg.c
   imgpng.c
   japp.c
   japp.h
   jview.c
   jview.h
   jwindow.c
   jwindow.h
   keysyms.h
   libawt.la
   Makefile.am
   Makefile.in
   tlk.c
   tlkprops.h
   toolkit.h
   wnd.c

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
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
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
/**
 * imgpng.c - interface for libpng input routines
 *
 * Copyright (c) 1998
 *      Transvirtual Technologies, Inc.  All rights reserved.
 *
 * See the file "license.terms" for information on usage and redistribution 
 * of this file. 
 */

#if NO_NEED

#include "toolkit.h"

#if defined(HAVE_PNG_H) && defined(HAVE_LIBPNG) && defined(HAVE_LIBZ)
#define INCLUDE_PNG
#endif

#if defined(INCLUDE_PNG)

#include "png.h"


/* references to img.c */
Image* createImage ( int width, int height );
void Java_java_awt_Toolkit_imgFreeImage( JNIEnv* env, jclass clazz, Image * img);
void createXImage ( Toolkit* X, Image* img );
void createXMaskImage ( Toolkit* X, Image* img );
void createAlphaImage ( Toolkit* X, Image* img );
void reduceAlpha ( Toolkit* X, Image* img, int threshold );


/**************************************************************************************
 * auxiliary funtions
 */

__inline__ int
hasAlpha ( png_structp png_ptr )
{
  return  (png_ptr->color_type == PNG_COLOR_TYPE_GRAY_ALPHA ||
		   png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA);

}

__inline__ jint
readARGB ( unsigned char** p, int hasAlpha )
{
  jint argb;

  argb = *(*p)++;
  argb <<= 8;
  argb += *(*p)++;
  argb <<= 8;
  argb += *(*p)++;

  if ( hasAlpha ) {
	argb <<= 8; 
	argb += *(*p)++;
  }

  return argb;
}


__inline__ void
setPixel ( Image* img, unsigned long argb, int row, int col )
{
  if ( img->alpha ){
	PutAlpha( img->alpha, col, row, argb >> 24);
  }

  XPutPixel( img->xImg, col, row, pixelValue( X, argb));
}


void
readRowData ( png_structp png_ptr, png_infop info_ptr, png_bytep row, Image *img )
{
  int            i, j;
  jint           argb;
  unsigned char  *p;

  for ( i = 0; i < info_ptr->height; i++ ) {
	png_read_row( png_ptr, row, 0);

	for ( j=0, p=(unsigned char*)row; j<info_ptr->width; j++ ) {
	  argb = readARGB( &p, (img->alpha != 0));
	  setPixel( img, argb, i, j);
	}
  }
}

void
readImageData ( png_structp png_ptr, png_infop info_ptr, png_bytepp rows, Image *img )
{
  int            i, j;
  jint           argb;
  unsigned char  *p;

  png_read_image( png_ptr, rows);

  for ( i=0; i<info_ptr->height; i++ ) {
	for ( j=0, p=(unsigned char*)rows[i]; j<info_ptr->width; j++ ) {
	  argb = readARGB( &p, (img->alpha != 0));
	  setPixel( img, argb, i, j);
	}
  }
}

void
readbackRow ( Image *img, unsigned char* rowBuf, int row )
{
  int            i;
  unsigned char  *p;
  int            r, g, b, a;
  unsigned long  pix;

  for ( i=0, p=rowBuf; i<img->width; i++ ) {
	pix = XGetPixel( img->xImg, i, row);
	rgbValues( X, pix, &r, &g, &b);

	a = (img->alpha) ? GetAlpha( img->alpha, i, row) : 0xff;

	*p++ = a;
	*p++ = r;
	*p++ = g;
	*p++ = b;
  }
}

/*
 * THIS DOESN'T WORK YET. The idea is to avoid allocating temporary
 * memory for the WHOLE image in ARGB pels (but ADAM7 seems to require
 * neighbor rows, too)
 */
void
readInterlacedData ( png_structp png_ptr, png_infop info_ptr, png_bytep row, Image *img )
{
  int   i, j, pass;
  jint           argb;
  unsigned char  *p;


  for ( pass=0; pass<7; pass++ ) {
	for ( i = 0; i < info_ptr->height; i++ ) {
	  if ( pass ) {
		readbackRow( img, row, i);
	  }
	  png_read_row( png_ptr, row, 0);

	  for ( j=0, p=(unsigned char*)row; j<info_ptr->width; j++ ) {
		argb = readARGB( &p, (img->alpha != 0));
		setPixel( img, argb, i, j);
	  }
	}
  }
}


Image*
readPng ( png_structp png_ptr, png_infop info_ptr )
{
  Image          *volatile img = 0;
  double         screen_gamma = 1.2, file_gamma;
  int            i, number_passes;
  int            row_bytes;
  png_bytepp     volatile rows = 0;
  png_bytep      volatile data = 0;

  if ( setjmp(png_ptr->jmpbuf) ) {
	if ( img )
	  Java_java_awt_Toolkit_imgFreeImage( 0, 0, img);
	if ( rows )
	  AWT_FREE( rows);
	if ( data )
	  AWT_FREE( data);
	return 0;
  }

  png_read_info( png_ptr, info_ptr);
  
  /* handle gamma correction  */
  {
#if defined(PNG_READ_sRGB_SUPPORTED)
	int intent;
	if ( png_get_sRGB( png_ptr, info_ptr, &intent) ) {
		png_set_sRGB( png_ptr, info_ptr, intent);
	}
	else
#endif
	if ( png_get_gAMA(png_ptr, info_ptr, &file_gamma) )
	  png_set_gamma( png_ptr, screen_gamma, file_gamma);
	else
	  png_set_gamma( png_ptr, screen_gamma, 0.50);
  }

  png_set_strip_16( png_ptr);
  png_set_expand( png_ptr);
  png_set_gray_to_rgb( png_ptr);
  png_set_swap_alpha( png_ptr); /* we need ARGB instead of the standard RGBA */

  row_bytes     = png_get_rowbytes( png_ptr, info_ptr);
  number_passes = png_set_interlace_handling( png_ptr);

  /* Optional call to gamma correct and add the background to the palette */
  png_read_update_info( png_ptr, info_ptr);

  /* time to create the image */
  img = createImage( info_ptr->width, info_ptr->height);
  if ( hasAlpha( png_ptr) )
	createAlphaImage( X, img);
  createXImage( X, img);

  if ( info_ptr->interlace_type != 0 ) {
#ifndef OPTIMIZE_SPACE
	/*
	 * This is bad: to read an interlaced image, we need enough space to (temporarily)
	 * store the whole transformed data (passes need prev. results). Unfortunately,
	 * interlacing is used for large images, and this might require a LOT of memory.
	 */
	rows = AWT_MALLOC( sizeof(png_bytep) * info_ptr->height);
	data = AWT_MALLOC( row_bytes * info_ptr->height);
	for ( i=0; i<info_ptr->height; i++ )
	  rows[i] = (data + i*row_bytes);

	readImageData( png_ptr, info_ptr, rows, img);

	AWT_FREE( rows);
	AWT_FREE( data);
#else
	data = AWT_MALLOC( row_bytes);
	readInterlacedData( png_ptr, info_ptr, data, img);
	AWT_FREE( data);
#endif
  }
  else {
	data = AWT_MALLOC( row_bytes);
	readRowData( png_ptr, info_ptr, data, img);
	AWT_FREE( data);
  }

  /* read rest of file, and get additional chunks in info_ptr */
  png_read_end( png_ptr, info_ptr);

  /* try to reduce alphas in the name of efficiency */
  if ( img->alpha &&  !needsFullAlpha( X, img, 0.01) )
	reduceAlpha( X, img, 128);

  return img;
}


/**************************************************************************************
 * memory buffer IO
 */

typedef struct {
  unsigned char *buf;
  unsigned char *p;
  long          remain;
} BufferSource;

void 
bufferRead ( png_structp png_ptr, png_bytep data, png_size_t length )
{
  BufferSource *psource = png_get_io_ptr( png_ptr);

  if ( psource->remain >= length ) {
	memcpy( data, psource->p, length);
	psource->p += length;
	psource->remain -= length;
  }
  else
	png_error( png_ptr, "illegal data read");
}


#endif /* INCLUDE_PNG */

/**************************************************************************************
 * these are the "exported" production interface functions
 */

Image*
readPngFile ( FILE* infile )
{
  Image          *img = 0;
#if defined(INCLUDE_PNG)
  png_structp    png_ptr;
  png_infop      info_ptr;

  png_ptr = png_create_read_struct( PNG_LIBPNG_VER_STRING,
									(png_voidp)0, (png_error_ptr)0, (png_error_ptr)0);
  if ( !png_ptr )
	return 0;

  info_ptr = png_create_info_struct( png_ptr);
  png_init_io( png_ptr, infile);

  img = readPng( png_ptr, info_ptr);

  png_destroy_read_struct( &png_ptr, &info_ptr, (png_infopp)NULL);
#endif /* INCLUDE_PNG */

  return img;
}


Image*
readPngData ( unsigned char* buf, long len )
{
  Image          *img = 0;
#if defined(INCLUDE_PNG)
  png_structp    png_ptr;
  png_infop      info_ptr;
  BufferSource   source;

  source.buf = source.p = buf;
  source.remain = len;

  png_ptr = png_create_read_struct( PNG_LIBPNG_VER_STRING,
									(png_voidp)0, (png_error_ptr)0, (png_error_ptr)0);
  if ( !png_ptr )
	return 0;

  info_ptr = png_create_info_struct( png_ptr);
  png_set_read_fn( png_ptr, &source, bufferRead);

  img = readPng( png_ptr, info_ptr);

  png_destroy_read_struct( &png_ptr, &info_ptr, (png_infopp)NULL);
#endif /* INCLUDE_PNG */

  return img;
}

#endif /* NO_NEED */

About Koders | Resources | Downloads | Support | Black Duck | Submit Project | Terms of Service | DMCA | Privacy Policy | Site Map| Contact Us