Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/java.desktop/share/native/libsplashscreen/libpng/pngget.c
41155 views
1
/*
2
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
3
*
4
* This code is free software; you can redistribute it and/or modify it
5
* under the terms of the GNU General Public License version 2 only, as
6
* published by the Free Software Foundation. Oracle designates this
7
* particular file as subject to the "Classpath" exception as provided
8
* by Oracle in the LICENSE file that accompanied this code.
9
*
10
* This code is distributed in the hope that it will be useful, but WITHOUT
11
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13
* version 2 for more details (a copy is included in the LICENSE file that
14
* accompanied this code).
15
*
16
* You should have received a copy of the GNU General Public License version
17
* 2 along with this work; if not, write to the Free Software Foundation,
18
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
19
*
20
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
21
* or visit www.oracle.com if you need additional information or have any
22
* questions.
23
*/
24
25
/* pngget.c - retrieval of values from info struct
26
*
27
* This file is available under and governed by the GNU General Public
28
* License version 2 only, as published by the Free Software Foundation.
29
* However, the following notice accompanied the original version of this
30
* file and, per its terms, should not be removed:
31
*
32
* Copyright (c) 2018 Cosmin Truta
33
* Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson
34
* Copyright (c) 1996-1997 Andreas Dilger
35
* Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
36
*
37
* This code is released under the libpng license.
38
* For conditions of distribution and use, see the disclaimer
39
* and license in png.h
40
*
41
*/
42
43
#include "pngpriv.h"
44
45
#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
46
47
png_uint_32 PNGAPI
48
png_get_valid(png_const_structrp png_ptr, png_const_inforp info_ptr,
49
png_uint_32 flag)
50
{
51
if (png_ptr != NULL && info_ptr != NULL)
52
return(info_ptr->valid & flag);
53
54
return(0);
55
}
56
57
size_t PNGAPI
58
png_get_rowbytes(png_const_structrp png_ptr, png_const_inforp info_ptr)
59
{
60
if (png_ptr != NULL && info_ptr != NULL)
61
return(info_ptr->rowbytes);
62
63
return(0);
64
}
65
66
#ifdef PNG_INFO_IMAGE_SUPPORTED
67
png_bytepp PNGAPI
68
png_get_rows(png_const_structrp png_ptr, png_const_inforp info_ptr)
69
{
70
if (png_ptr != NULL && info_ptr != NULL)
71
return(info_ptr->row_pointers);
72
73
return(0);
74
}
75
#endif
76
77
#ifdef PNG_EASY_ACCESS_SUPPORTED
78
/* Easy access to info, added in libpng-0.99 */
79
png_uint_32 PNGAPI
80
png_get_image_width(png_const_structrp png_ptr, png_const_inforp info_ptr)
81
{
82
if (png_ptr != NULL && info_ptr != NULL)
83
return info_ptr->width;
84
85
return (0);
86
}
87
88
png_uint_32 PNGAPI
89
png_get_image_height(png_const_structrp png_ptr, png_const_inforp info_ptr)
90
{
91
if (png_ptr != NULL && info_ptr != NULL)
92
return info_ptr->height;
93
94
return (0);
95
}
96
97
png_byte PNGAPI
98
png_get_bit_depth(png_const_structrp png_ptr, png_const_inforp info_ptr)
99
{
100
if (png_ptr != NULL && info_ptr != NULL)
101
return info_ptr->bit_depth;
102
103
return (0);
104
}
105
106
png_byte PNGAPI
107
png_get_color_type(png_const_structrp png_ptr, png_const_inforp info_ptr)
108
{
109
if (png_ptr != NULL && info_ptr != NULL)
110
return info_ptr->color_type;
111
112
return (0);
113
}
114
115
png_byte PNGAPI
116
png_get_filter_type(png_const_structrp png_ptr, png_const_inforp info_ptr)
117
{
118
if (png_ptr != NULL && info_ptr != NULL)
119
return info_ptr->filter_type;
120
121
return (0);
122
}
123
124
png_byte PNGAPI
125
png_get_interlace_type(png_const_structrp png_ptr, png_const_inforp info_ptr)
126
{
127
if (png_ptr != NULL && info_ptr != NULL)
128
return info_ptr->interlace_type;
129
130
return (0);
131
}
132
133
png_byte PNGAPI
134
png_get_compression_type(png_const_structrp png_ptr, png_const_inforp info_ptr)
135
{
136
if (png_ptr != NULL && info_ptr != NULL)
137
return info_ptr->compression_type;
138
139
return (0);
140
}
141
142
png_uint_32 PNGAPI
143
png_get_x_pixels_per_meter(png_const_structrp png_ptr, png_const_inforp
144
info_ptr)
145
{
146
#ifdef PNG_pHYs_SUPPORTED
147
if (png_ptr != NULL && info_ptr != NULL &&
148
(info_ptr->valid & PNG_INFO_pHYs) != 0)
149
{
150
png_debug1(1, "in %s retrieval function",
151
"png_get_x_pixels_per_meter");
152
153
if (info_ptr->phys_unit_type == PNG_RESOLUTION_METER)
154
return (info_ptr->x_pixels_per_unit);
155
}
156
#else
157
PNG_UNUSED(png_ptr)
158
PNG_UNUSED(info_ptr)
159
#endif
160
161
return (0);
162
}
163
164
png_uint_32 PNGAPI
165
png_get_y_pixels_per_meter(png_const_structrp png_ptr, png_const_inforp
166
info_ptr)
167
{
168
#ifdef PNG_pHYs_SUPPORTED
169
if (png_ptr != NULL && info_ptr != NULL &&
170
(info_ptr->valid & PNG_INFO_pHYs) != 0)
171
{
172
png_debug1(1, "in %s retrieval function",
173
"png_get_y_pixels_per_meter");
174
175
if (info_ptr->phys_unit_type == PNG_RESOLUTION_METER)
176
return (info_ptr->y_pixels_per_unit);
177
}
178
#else
179
PNG_UNUSED(png_ptr)
180
PNG_UNUSED(info_ptr)
181
#endif
182
183
return (0);
184
}
185
186
png_uint_32 PNGAPI
187
png_get_pixels_per_meter(png_const_structrp png_ptr, png_const_inforp info_ptr)
188
{
189
#ifdef PNG_pHYs_SUPPORTED
190
if (png_ptr != NULL && info_ptr != NULL &&
191
(info_ptr->valid & PNG_INFO_pHYs) != 0)
192
{
193
png_debug1(1, "in %s retrieval function", "png_get_pixels_per_meter");
194
195
if (info_ptr->phys_unit_type == PNG_RESOLUTION_METER &&
196
info_ptr->x_pixels_per_unit == info_ptr->y_pixels_per_unit)
197
return (info_ptr->x_pixels_per_unit);
198
}
199
#else
200
PNG_UNUSED(png_ptr)
201
PNG_UNUSED(info_ptr)
202
#endif
203
204
return (0);
205
}
206
207
#ifdef PNG_FLOATING_POINT_SUPPORTED
208
float PNGAPI
209
png_get_pixel_aspect_ratio(png_const_structrp png_ptr, png_const_inforp
210
info_ptr)
211
{
212
#ifdef PNG_READ_pHYs_SUPPORTED
213
if (png_ptr != NULL && info_ptr != NULL &&
214
(info_ptr->valid & PNG_INFO_pHYs) != 0)
215
{
216
png_debug1(1, "in %s retrieval function", "png_get_aspect_ratio");
217
218
if (info_ptr->x_pixels_per_unit != 0)
219
return ((float)((float)info_ptr->y_pixels_per_unit
220
/(float)info_ptr->x_pixels_per_unit));
221
}
222
#else
223
PNG_UNUSED(png_ptr)
224
PNG_UNUSED(info_ptr)
225
#endif
226
227
return ((float)0.0);
228
}
229
#endif
230
231
#ifdef PNG_FIXED_POINT_SUPPORTED
232
png_fixed_point PNGAPI
233
png_get_pixel_aspect_ratio_fixed(png_const_structrp png_ptr,
234
png_const_inforp info_ptr)
235
{
236
#ifdef PNG_READ_pHYs_SUPPORTED
237
if (png_ptr != NULL && info_ptr != NULL &&
238
(info_ptr->valid & PNG_INFO_pHYs) != 0 &&
239
info_ptr->x_pixels_per_unit > 0 && info_ptr->y_pixels_per_unit > 0 &&
240
info_ptr->x_pixels_per_unit <= PNG_UINT_31_MAX &&
241
info_ptr->y_pixels_per_unit <= PNG_UINT_31_MAX)
242
{
243
png_fixed_point res;
244
245
png_debug1(1, "in %s retrieval function", "png_get_aspect_ratio_fixed");
246
247
/* The following casts work because a PNG 4 byte integer only has a valid
248
* range of 0..2^31-1; otherwise the cast might overflow.
249
*/
250
if (png_muldiv(&res, (png_int_32)info_ptr->y_pixels_per_unit, PNG_FP_1,
251
(png_int_32)info_ptr->x_pixels_per_unit) != 0)
252
return res;
253
}
254
#else
255
PNG_UNUSED(png_ptr)
256
PNG_UNUSED(info_ptr)
257
#endif
258
259
return 0;
260
}
261
#endif
262
263
png_int_32 PNGAPI
264
png_get_x_offset_microns(png_const_structrp png_ptr, png_const_inforp info_ptr)
265
{
266
#ifdef PNG_oFFs_SUPPORTED
267
if (png_ptr != NULL && info_ptr != NULL &&
268
(info_ptr->valid & PNG_INFO_oFFs) != 0)
269
{
270
png_debug1(1, "in %s retrieval function", "png_get_x_offset_microns");
271
272
if (info_ptr->offset_unit_type == PNG_OFFSET_MICROMETER)
273
return (info_ptr->x_offset);
274
}
275
#else
276
PNG_UNUSED(png_ptr)
277
PNG_UNUSED(info_ptr)
278
#endif
279
280
return (0);
281
}
282
283
png_int_32 PNGAPI
284
png_get_y_offset_microns(png_const_structrp png_ptr, png_const_inforp info_ptr)
285
{
286
#ifdef PNG_oFFs_SUPPORTED
287
if (png_ptr != NULL && info_ptr != NULL &&
288
(info_ptr->valid & PNG_INFO_oFFs) != 0)
289
{
290
png_debug1(1, "in %s retrieval function", "png_get_y_offset_microns");
291
292
if (info_ptr->offset_unit_type == PNG_OFFSET_MICROMETER)
293
return (info_ptr->y_offset);
294
}
295
#else
296
PNG_UNUSED(png_ptr)
297
PNG_UNUSED(info_ptr)
298
#endif
299
300
return (0);
301
}
302
303
png_int_32 PNGAPI
304
png_get_x_offset_pixels(png_const_structrp png_ptr, png_const_inforp info_ptr)
305
{
306
#ifdef PNG_oFFs_SUPPORTED
307
if (png_ptr != NULL && info_ptr != NULL &&
308
(info_ptr->valid & PNG_INFO_oFFs) != 0)
309
{
310
png_debug1(1, "in %s retrieval function", "png_get_x_offset_pixels");
311
312
if (info_ptr->offset_unit_type == PNG_OFFSET_PIXEL)
313
return (info_ptr->x_offset);
314
}
315
#else
316
PNG_UNUSED(png_ptr)
317
PNG_UNUSED(info_ptr)
318
#endif
319
320
return (0);
321
}
322
323
png_int_32 PNGAPI
324
png_get_y_offset_pixels(png_const_structrp png_ptr, png_const_inforp info_ptr)
325
{
326
#ifdef PNG_oFFs_SUPPORTED
327
if (png_ptr != NULL && info_ptr != NULL &&
328
(info_ptr->valid & PNG_INFO_oFFs) != 0)
329
{
330
png_debug1(1, "in %s retrieval function", "png_get_y_offset_pixels");
331
332
if (info_ptr->offset_unit_type == PNG_OFFSET_PIXEL)
333
return (info_ptr->y_offset);
334
}
335
#else
336
PNG_UNUSED(png_ptr)
337
PNG_UNUSED(info_ptr)
338
#endif
339
340
return (0);
341
}
342
343
#ifdef PNG_INCH_CONVERSIONS_SUPPORTED
344
static png_uint_32
345
ppi_from_ppm(png_uint_32 ppm)
346
{
347
#if 0
348
/* The conversion is *(2.54/100), in binary (32 digits):
349
* .00000110100000001001110101001001
350
*/
351
png_uint_32 t1001, t1101;
352
ppm >>= 1; /* .1 */
353
t1001 = ppm + (ppm >> 3); /* .1001 */
354
t1101 = t1001 + (ppm >> 1); /* .1101 */
355
ppm >>= 20; /* .000000000000000000001 */
356
t1101 += t1101 >> 15; /* .1101000000000001101 */
357
t1001 >>= 11; /* .000000000001001 */
358
t1001 += t1001 >> 12; /* .000000000001001000000001001 */
359
ppm += t1001; /* .000000000001001000001001001 */
360
ppm += t1101; /* .110100000001001110101001001 */
361
return (ppm + 16) >> 5;/* .00000110100000001001110101001001 */
362
#else
363
/* The argument is a PNG unsigned integer, so it is not permitted
364
* to be bigger than 2^31.
365
*/
366
png_fixed_point result;
367
if (ppm <= PNG_UINT_31_MAX && png_muldiv(&result, (png_int_32)ppm, 127,
368
5000) != 0)
369
return (png_uint_32)result;
370
371
/* Overflow. */
372
return 0;
373
#endif
374
}
375
376
png_uint_32 PNGAPI
377
png_get_pixels_per_inch(png_const_structrp png_ptr, png_const_inforp info_ptr)
378
{
379
return ppi_from_ppm(png_get_pixels_per_meter(png_ptr, info_ptr));
380
}
381
382
png_uint_32 PNGAPI
383
png_get_x_pixels_per_inch(png_const_structrp png_ptr, png_const_inforp info_ptr)
384
{
385
return ppi_from_ppm(png_get_x_pixels_per_meter(png_ptr, info_ptr));
386
}
387
388
png_uint_32 PNGAPI
389
png_get_y_pixels_per_inch(png_const_structrp png_ptr, png_const_inforp info_ptr)
390
{
391
return ppi_from_ppm(png_get_y_pixels_per_meter(png_ptr, info_ptr));
392
}
393
394
#ifdef PNG_FIXED_POINT_SUPPORTED
395
static png_fixed_point
396
png_fixed_inches_from_microns(png_const_structrp png_ptr, png_int_32 microns)
397
{
398
/* Convert from meters * 1,000,000 to inches * 100,000, meters to
399
* inches is simply *(100/2.54), so we want *(10/2.54) == 500/127.
400
* Notice that this can overflow - a warning is output and 0 is
401
* returned.
402
*/
403
return png_muldiv_warn(png_ptr, microns, 500, 127);
404
}
405
406
png_fixed_point PNGAPI
407
png_get_x_offset_inches_fixed(png_const_structrp png_ptr,
408
png_const_inforp info_ptr)
409
{
410
return png_fixed_inches_from_microns(png_ptr,
411
png_get_x_offset_microns(png_ptr, info_ptr));
412
}
413
#endif
414
415
#ifdef PNG_FIXED_POINT_SUPPORTED
416
png_fixed_point PNGAPI
417
png_get_y_offset_inches_fixed(png_const_structrp png_ptr,
418
png_const_inforp info_ptr)
419
{
420
return png_fixed_inches_from_microns(png_ptr,
421
png_get_y_offset_microns(png_ptr, info_ptr));
422
}
423
#endif
424
425
#ifdef PNG_FLOATING_POINT_SUPPORTED
426
float PNGAPI
427
png_get_x_offset_inches(png_const_structrp png_ptr, png_const_inforp info_ptr)
428
{
429
/* To avoid the overflow do the conversion directly in floating
430
* point.
431
*/
432
return (float)(png_get_x_offset_microns(png_ptr, info_ptr) * .00003937);
433
}
434
#endif
435
436
#ifdef PNG_FLOATING_POINT_SUPPORTED
437
float PNGAPI
438
png_get_y_offset_inches(png_const_structrp png_ptr, png_const_inforp info_ptr)
439
{
440
/* To avoid the overflow do the conversion directly in floating
441
* point.
442
*/
443
return (float)(png_get_y_offset_microns(png_ptr, info_ptr) * .00003937);
444
}
445
#endif
446
447
#ifdef PNG_pHYs_SUPPORTED
448
png_uint_32 PNGAPI
449
png_get_pHYs_dpi(png_const_structrp png_ptr, png_const_inforp info_ptr,
450
png_uint_32 *res_x, png_uint_32 *res_y, int *unit_type)
451
{
452
png_uint_32 retval = 0;
453
454
if (png_ptr != NULL && info_ptr != NULL &&
455
(info_ptr->valid & PNG_INFO_pHYs) != 0)
456
{
457
png_debug1(1, "in %s retrieval function", "pHYs");
458
459
if (res_x != NULL)
460
{
461
*res_x = info_ptr->x_pixels_per_unit;
462
retval |= PNG_INFO_pHYs;
463
}
464
465
if (res_y != NULL)
466
{
467
*res_y = info_ptr->y_pixels_per_unit;
468
retval |= PNG_INFO_pHYs;
469
}
470
471
if (unit_type != NULL)
472
{
473
*unit_type = (int)info_ptr->phys_unit_type;
474
retval |= PNG_INFO_pHYs;
475
476
if (*unit_type == 1)
477
{
478
if (res_x != NULL) *res_x = (png_uint_32)(*res_x * .0254 + .50);
479
if (res_y != NULL) *res_y = (png_uint_32)(*res_y * .0254 + .50);
480
}
481
}
482
}
483
484
return (retval);
485
}
486
#endif /* pHYs */
487
#endif /* INCH_CONVERSIONS */
488
489
/* png_get_channels really belongs in here, too, but it's been around longer */
490
491
#endif /* EASY_ACCESS */
492
493
494
png_byte PNGAPI
495
png_get_channels(png_const_structrp png_ptr, png_const_inforp info_ptr)
496
{
497
if (png_ptr != NULL && info_ptr != NULL)
498
return(info_ptr->channels);
499
500
return (0);
501
}
502
503
#ifdef PNG_READ_SUPPORTED
504
png_const_bytep PNGAPI
505
png_get_signature(png_const_structrp png_ptr, png_const_inforp info_ptr)
506
{
507
if (png_ptr != NULL && info_ptr != NULL)
508
return(info_ptr->signature);
509
510
return (NULL);
511
}
512
#endif
513
514
#ifdef PNG_bKGD_SUPPORTED
515
png_uint_32 PNGAPI
516
png_get_bKGD(png_const_structrp png_ptr, png_inforp info_ptr,
517
png_color_16p *background)
518
{
519
if (png_ptr != NULL && info_ptr != NULL &&
520
(info_ptr->valid & PNG_INFO_bKGD) != 0 &&
521
background != NULL)
522
{
523
png_debug1(1, "in %s retrieval function", "bKGD");
524
525
*background = &(info_ptr->background);
526
return (PNG_INFO_bKGD);
527
}
528
529
return (0);
530
}
531
#endif
532
533
#ifdef PNG_cHRM_SUPPORTED
534
/* The XYZ APIs were added in 1.5.5 to take advantage of the code added at the
535
* same time to correct the rgb grayscale coefficient defaults obtained from the
536
* cHRM chunk in 1.5.4
537
*/
538
# ifdef PNG_FLOATING_POINT_SUPPORTED
539
png_uint_32 PNGAPI
540
png_get_cHRM(png_const_structrp png_ptr, png_const_inforp info_ptr,
541
double *white_x, double *white_y, double *red_x, double *red_y,
542
double *green_x, double *green_y, double *blue_x, double *blue_y)
543
{
544
/* Quiet API change: this code used to only return the end points if a cHRM
545
* chunk was present, but the end points can also come from iCCP or sRGB
546
* chunks, so in 1.6.0 the png_get_ APIs return the end points regardless and
547
* the png_set_ APIs merely check that set end points are mutually
548
* consistent.
549
*/
550
if (png_ptr != NULL && info_ptr != NULL &&
551
(info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_ENDPOINTS) != 0)
552
{
553
png_debug1(1, "in %s retrieval function", "cHRM");
554
555
if (white_x != NULL)
556
*white_x = png_float(png_ptr,
557
info_ptr->colorspace.end_points_xy.whitex, "cHRM white X");
558
if (white_y != NULL)
559
*white_y = png_float(png_ptr,
560
info_ptr->colorspace.end_points_xy.whitey, "cHRM white Y");
561
if (red_x != NULL)
562
*red_x = png_float(png_ptr, info_ptr->colorspace.end_points_xy.redx,
563
"cHRM red X");
564
if (red_y != NULL)
565
*red_y = png_float(png_ptr, info_ptr->colorspace.end_points_xy.redy,
566
"cHRM red Y");
567
if (green_x != NULL)
568
*green_x = png_float(png_ptr,
569
info_ptr->colorspace.end_points_xy.greenx, "cHRM green X");
570
if (green_y != NULL)
571
*green_y = png_float(png_ptr,
572
info_ptr->colorspace.end_points_xy.greeny, "cHRM green Y");
573
if (blue_x != NULL)
574
*blue_x = png_float(png_ptr, info_ptr->colorspace.end_points_xy.bluex,
575
"cHRM blue X");
576
if (blue_y != NULL)
577
*blue_y = png_float(png_ptr, info_ptr->colorspace.end_points_xy.bluey,
578
"cHRM blue Y");
579
return (PNG_INFO_cHRM);
580
}
581
582
return (0);
583
}
584
585
png_uint_32 PNGAPI
586
png_get_cHRM_XYZ(png_const_structrp png_ptr, png_const_inforp info_ptr,
587
double *red_X, double *red_Y, double *red_Z, double *green_X,
588
double *green_Y, double *green_Z, double *blue_X, double *blue_Y,
589
double *blue_Z)
590
{
591
if (png_ptr != NULL && info_ptr != NULL &&
592
(info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_ENDPOINTS) != 0)
593
{
594
png_debug1(1, "in %s retrieval function", "cHRM_XYZ(float)");
595
596
if (red_X != NULL)
597
*red_X = png_float(png_ptr, info_ptr->colorspace.end_points_XYZ.red_X,
598
"cHRM red X");
599
if (red_Y != NULL)
600
*red_Y = png_float(png_ptr, info_ptr->colorspace.end_points_XYZ.red_Y,
601
"cHRM red Y");
602
if (red_Z != NULL)
603
*red_Z = png_float(png_ptr, info_ptr->colorspace.end_points_XYZ.red_Z,
604
"cHRM red Z");
605
if (green_X != NULL)
606
*green_X = png_float(png_ptr,
607
info_ptr->colorspace.end_points_XYZ.green_X, "cHRM green X");
608
if (green_Y != NULL)
609
*green_Y = png_float(png_ptr,
610
info_ptr->colorspace.end_points_XYZ.green_Y, "cHRM green Y");
611
if (green_Z != NULL)
612
*green_Z = png_float(png_ptr,
613
info_ptr->colorspace.end_points_XYZ.green_Z, "cHRM green Z");
614
if (blue_X != NULL)
615
*blue_X = png_float(png_ptr,
616
info_ptr->colorspace.end_points_XYZ.blue_X, "cHRM blue X");
617
if (blue_Y != NULL)
618
*blue_Y = png_float(png_ptr,
619
info_ptr->colorspace.end_points_XYZ.blue_Y, "cHRM blue Y");
620
if (blue_Z != NULL)
621
*blue_Z = png_float(png_ptr,
622
info_ptr->colorspace.end_points_XYZ.blue_Z, "cHRM blue Z");
623
return (PNG_INFO_cHRM);
624
}
625
626
return (0);
627
}
628
# endif
629
630
# ifdef PNG_FIXED_POINT_SUPPORTED
631
png_uint_32 PNGAPI
632
png_get_cHRM_XYZ_fixed(png_const_structrp png_ptr, png_const_inforp info_ptr,
633
png_fixed_point *int_red_X, png_fixed_point *int_red_Y,
634
png_fixed_point *int_red_Z, png_fixed_point *int_green_X,
635
png_fixed_point *int_green_Y, png_fixed_point *int_green_Z,
636
png_fixed_point *int_blue_X, png_fixed_point *int_blue_Y,
637
png_fixed_point *int_blue_Z)
638
{
639
if (png_ptr != NULL && info_ptr != NULL &&
640
(info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_ENDPOINTS) != 0)
641
{
642
png_debug1(1, "in %s retrieval function", "cHRM_XYZ");
643
644
if (int_red_X != NULL)
645
*int_red_X = info_ptr->colorspace.end_points_XYZ.red_X;
646
if (int_red_Y != NULL)
647
*int_red_Y = info_ptr->colorspace.end_points_XYZ.red_Y;
648
if (int_red_Z != NULL)
649
*int_red_Z = info_ptr->colorspace.end_points_XYZ.red_Z;
650
if (int_green_X != NULL)
651
*int_green_X = info_ptr->colorspace.end_points_XYZ.green_X;
652
if (int_green_Y != NULL)
653
*int_green_Y = info_ptr->colorspace.end_points_XYZ.green_Y;
654
if (int_green_Z != NULL)
655
*int_green_Z = info_ptr->colorspace.end_points_XYZ.green_Z;
656
if (int_blue_X != NULL)
657
*int_blue_X = info_ptr->colorspace.end_points_XYZ.blue_X;
658
if (int_blue_Y != NULL)
659
*int_blue_Y = info_ptr->colorspace.end_points_XYZ.blue_Y;
660
if (int_blue_Z != NULL)
661
*int_blue_Z = info_ptr->colorspace.end_points_XYZ.blue_Z;
662
return (PNG_INFO_cHRM);
663
}
664
665
return (0);
666
}
667
668
png_uint_32 PNGAPI
669
png_get_cHRM_fixed(png_const_structrp png_ptr, png_const_inforp info_ptr,
670
png_fixed_point *white_x, png_fixed_point *white_y, png_fixed_point *red_x,
671
png_fixed_point *red_y, png_fixed_point *green_x, png_fixed_point *green_y,
672
png_fixed_point *blue_x, png_fixed_point *blue_y)
673
{
674
png_debug1(1, "in %s retrieval function", "cHRM");
675
676
if (png_ptr != NULL && info_ptr != NULL &&
677
(info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_ENDPOINTS) != 0)
678
{
679
if (white_x != NULL)
680
*white_x = info_ptr->colorspace.end_points_xy.whitex;
681
if (white_y != NULL)
682
*white_y = info_ptr->colorspace.end_points_xy.whitey;
683
if (red_x != NULL)
684
*red_x = info_ptr->colorspace.end_points_xy.redx;
685
if (red_y != NULL)
686
*red_y = info_ptr->colorspace.end_points_xy.redy;
687
if (green_x != NULL)
688
*green_x = info_ptr->colorspace.end_points_xy.greenx;
689
if (green_y != NULL)
690
*green_y = info_ptr->colorspace.end_points_xy.greeny;
691
if (blue_x != NULL)
692
*blue_x = info_ptr->colorspace.end_points_xy.bluex;
693
if (blue_y != NULL)
694
*blue_y = info_ptr->colorspace.end_points_xy.bluey;
695
return (PNG_INFO_cHRM);
696
}
697
698
return (0);
699
}
700
# endif
701
#endif
702
703
#ifdef PNG_gAMA_SUPPORTED
704
# ifdef PNG_FIXED_POINT_SUPPORTED
705
png_uint_32 PNGAPI
706
png_get_gAMA_fixed(png_const_structrp png_ptr, png_const_inforp info_ptr,
707
png_fixed_point *file_gamma)
708
{
709
png_debug1(1, "in %s retrieval function", "gAMA");
710
711
if (png_ptr != NULL && info_ptr != NULL &&
712
(info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_GAMMA) != 0 &&
713
file_gamma != NULL)
714
{
715
*file_gamma = info_ptr->colorspace.gamma;
716
return (PNG_INFO_gAMA);
717
}
718
719
return (0);
720
}
721
# endif
722
723
# ifdef PNG_FLOATING_POINT_SUPPORTED
724
png_uint_32 PNGAPI
725
png_get_gAMA(png_const_structrp png_ptr, png_const_inforp info_ptr,
726
double *file_gamma)
727
{
728
png_debug1(1, "in %s retrieval function", "gAMA(float)");
729
730
if (png_ptr != NULL && info_ptr != NULL &&
731
(info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_GAMMA) != 0 &&
732
file_gamma != NULL)
733
{
734
*file_gamma = png_float(png_ptr, info_ptr->colorspace.gamma,
735
"png_get_gAMA");
736
return (PNG_INFO_gAMA);
737
}
738
739
return (0);
740
}
741
# endif
742
#endif
743
744
#ifdef PNG_sRGB_SUPPORTED
745
png_uint_32 PNGAPI
746
png_get_sRGB(png_const_structrp png_ptr, png_const_inforp info_ptr,
747
int *file_srgb_intent)
748
{
749
png_debug1(1, "in %s retrieval function", "sRGB");
750
751
if (png_ptr != NULL && info_ptr != NULL &&
752
(info_ptr->valid & PNG_INFO_sRGB) != 0 && file_srgb_intent != NULL)
753
{
754
*file_srgb_intent = info_ptr->colorspace.rendering_intent;
755
return (PNG_INFO_sRGB);
756
}
757
758
return (0);
759
}
760
#endif
761
762
#ifdef PNG_iCCP_SUPPORTED
763
png_uint_32 PNGAPI
764
png_get_iCCP(png_const_structrp png_ptr, png_inforp info_ptr,
765
png_charpp name, int *compression_type,
766
png_bytepp profile, png_uint_32 *proflen)
767
{
768
png_debug1(1, "in %s retrieval function", "iCCP");
769
770
if (png_ptr != NULL && info_ptr != NULL &&
771
(info_ptr->valid & PNG_INFO_iCCP) != 0 &&
772
name != NULL && profile != NULL && proflen != NULL)
773
{
774
*name = info_ptr->iccp_name;
775
*profile = info_ptr->iccp_profile;
776
*proflen = png_get_uint_32(info_ptr->iccp_profile);
777
/* This is somewhat irrelevant since the profile data returned has
778
* actually been uncompressed.
779
*/
780
if (compression_type != NULL)
781
*compression_type = PNG_COMPRESSION_TYPE_BASE;
782
return (PNG_INFO_iCCP);
783
}
784
785
return (0);
786
787
}
788
#endif
789
790
#ifdef PNG_sPLT_SUPPORTED
791
int PNGAPI
792
png_get_sPLT(png_const_structrp png_ptr, png_inforp info_ptr,
793
png_sPLT_tpp spalettes)
794
{
795
if (png_ptr != NULL && info_ptr != NULL && spalettes != NULL)
796
{
797
*spalettes = info_ptr->splt_palettes;
798
return info_ptr->splt_palettes_num;
799
}
800
801
return (0);
802
}
803
#endif
804
805
#ifdef PNG_eXIf_SUPPORTED
806
png_uint_32 PNGAPI
807
png_get_eXIf(png_const_structrp png_ptr, png_inforp info_ptr,
808
png_bytep *exif)
809
{
810
png_warning(png_ptr, "png_get_eXIf does not work; use png_get_eXIf_1");
811
PNG_UNUSED(info_ptr)
812
PNG_UNUSED(exif)
813
return 0;
814
}
815
816
png_uint_32 PNGAPI
817
png_get_eXIf_1(png_const_structrp png_ptr, png_const_inforp info_ptr,
818
png_uint_32 *num_exif, png_bytep *exif)
819
{
820
png_debug1(1, "in %s retrieval function", "eXIf");
821
822
if (png_ptr != NULL && info_ptr != NULL &&
823
(info_ptr->valid & PNG_INFO_eXIf) != 0 && exif != NULL)
824
{
825
*num_exif = info_ptr->num_exif;
826
*exif = info_ptr->exif;
827
return (PNG_INFO_eXIf);
828
}
829
830
return (0);
831
}
832
#endif
833
834
#ifdef PNG_hIST_SUPPORTED
835
png_uint_32 PNGAPI
836
png_get_hIST(png_const_structrp png_ptr, png_inforp info_ptr,
837
png_uint_16p *hist)
838
{
839
png_debug1(1, "in %s retrieval function", "hIST");
840
841
if (png_ptr != NULL && info_ptr != NULL &&
842
(info_ptr->valid & PNG_INFO_hIST) != 0 && hist != NULL)
843
{
844
*hist = info_ptr->hist;
845
return (PNG_INFO_hIST);
846
}
847
848
return (0);
849
}
850
#endif
851
852
png_uint_32 PNGAPI
853
png_get_IHDR(png_const_structrp png_ptr, png_const_inforp info_ptr,
854
png_uint_32 *width, png_uint_32 *height, int *bit_depth,
855
int *color_type, int *interlace_type, int *compression_type,
856
int *filter_type)
857
{
858
png_debug1(1, "in %s retrieval function", "IHDR");
859
860
if (png_ptr == NULL || info_ptr == NULL)
861
return (0);
862
863
if (width != NULL)
864
*width = info_ptr->width;
865
866
if (height != NULL)
867
*height = info_ptr->height;
868
869
if (bit_depth != NULL)
870
*bit_depth = info_ptr->bit_depth;
871
872
if (color_type != NULL)
873
*color_type = info_ptr->color_type;
874
875
if (compression_type != NULL)
876
*compression_type = info_ptr->compression_type;
877
878
if (filter_type != NULL)
879
*filter_type = info_ptr->filter_type;
880
881
if (interlace_type != NULL)
882
*interlace_type = info_ptr->interlace_type;
883
884
/* This is redundant if we can be sure that the info_ptr values were all
885
* assigned in png_set_IHDR(). We do the check anyhow in case an
886
* application has ignored our advice not to mess with the members
887
* of info_ptr directly.
888
*/
889
png_check_IHDR(png_ptr, info_ptr->width, info_ptr->height,
890
info_ptr->bit_depth, info_ptr->color_type, info_ptr->interlace_type,
891
info_ptr->compression_type, info_ptr->filter_type);
892
893
return (1);
894
}
895
896
#ifdef PNG_oFFs_SUPPORTED
897
png_uint_32 PNGAPI
898
png_get_oFFs(png_const_structrp png_ptr, png_const_inforp info_ptr,
899
png_int_32 *offset_x, png_int_32 *offset_y, int *unit_type)
900
{
901
png_debug1(1, "in %s retrieval function", "oFFs");
902
903
if (png_ptr != NULL && info_ptr != NULL &&
904
(info_ptr->valid & PNG_INFO_oFFs) != 0 &&
905
offset_x != NULL && offset_y != NULL && unit_type != NULL)
906
{
907
*offset_x = info_ptr->x_offset;
908
*offset_y = info_ptr->y_offset;
909
*unit_type = (int)info_ptr->offset_unit_type;
910
return (PNG_INFO_oFFs);
911
}
912
913
return (0);
914
}
915
#endif
916
917
#ifdef PNG_pCAL_SUPPORTED
918
png_uint_32 PNGAPI
919
png_get_pCAL(png_const_structrp png_ptr, png_inforp info_ptr,
920
png_charp *purpose, png_int_32 *X0, png_int_32 *X1, int *type, int *nparams,
921
png_charp *units, png_charpp *params)
922
{
923
png_debug1(1, "in %s retrieval function", "pCAL");
924
925
if (png_ptr != NULL && info_ptr != NULL &&
926
(info_ptr->valid & PNG_INFO_pCAL) != 0 &&
927
purpose != NULL && X0 != NULL && X1 != NULL && type != NULL &&
928
nparams != NULL && units != NULL && params != NULL)
929
{
930
*purpose = info_ptr->pcal_purpose;
931
*X0 = info_ptr->pcal_X0;
932
*X1 = info_ptr->pcal_X1;
933
*type = (int)info_ptr->pcal_type;
934
*nparams = (int)info_ptr->pcal_nparams;
935
*units = info_ptr->pcal_units;
936
*params = info_ptr->pcal_params;
937
return (PNG_INFO_pCAL);
938
}
939
940
return (0);
941
}
942
#endif
943
944
#ifdef PNG_sCAL_SUPPORTED
945
# ifdef PNG_FIXED_POINT_SUPPORTED
946
# if defined(PNG_FLOATING_ARITHMETIC_SUPPORTED) || \
947
defined(PNG_FLOATING_POINT_SUPPORTED)
948
png_uint_32 PNGAPI
949
png_get_sCAL_fixed(png_const_structrp png_ptr, png_const_inforp info_ptr,
950
int *unit, png_fixed_point *width, png_fixed_point *height)
951
{
952
if (png_ptr != NULL && info_ptr != NULL &&
953
(info_ptr->valid & PNG_INFO_sCAL) != 0)
954
{
955
*unit = info_ptr->scal_unit;
956
/*TODO: make this work without FP support; the API is currently eliminated
957
* if neither floating point APIs nor internal floating point arithmetic
958
* are enabled.
959
*/
960
*width = png_fixed(png_ptr, atof(info_ptr->scal_s_width), "sCAL width");
961
*height = png_fixed(png_ptr, atof(info_ptr->scal_s_height),
962
"sCAL height");
963
return (PNG_INFO_sCAL);
964
}
965
966
return(0);
967
}
968
# endif /* FLOATING_ARITHMETIC */
969
# endif /* FIXED_POINT */
970
# ifdef PNG_FLOATING_POINT_SUPPORTED
971
png_uint_32 PNGAPI
972
png_get_sCAL(png_const_structrp png_ptr, png_const_inforp info_ptr,
973
int *unit, double *width, double *height)
974
{
975
if (png_ptr != NULL && info_ptr != NULL &&
976
(info_ptr->valid & PNG_INFO_sCAL) != 0)
977
{
978
*unit = info_ptr->scal_unit;
979
*width = atof(info_ptr->scal_s_width);
980
*height = atof(info_ptr->scal_s_height);
981
return (PNG_INFO_sCAL);
982
}
983
984
return(0);
985
}
986
# endif /* FLOATING POINT */
987
png_uint_32 PNGAPI
988
png_get_sCAL_s(png_const_structrp png_ptr, png_const_inforp info_ptr,
989
int *unit, png_charpp width, png_charpp height)
990
{
991
if (png_ptr != NULL && info_ptr != NULL &&
992
(info_ptr->valid & PNG_INFO_sCAL) != 0)
993
{
994
*unit = info_ptr->scal_unit;
995
*width = info_ptr->scal_s_width;
996
*height = info_ptr->scal_s_height;
997
return (PNG_INFO_sCAL);
998
}
999
1000
return(0);
1001
}
1002
#endif /* sCAL */
1003
1004
#ifdef PNG_pHYs_SUPPORTED
1005
png_uint_32 PNGAPI
1006
png_get_pHYs(png_const_structrp png_ptr, png_const_inforp info_ptr,
1007
png_uint_32 *res_x, png_uint_32 *res_y, int *unit_type)
1008
{
1009
png_uint_32 retval = 0;
1010
1011
png_debug1(1, "in %s retrieval function", "pHYs");
1012
1013
if (png_ptr != NULL && info_ptr != NULL &&
1014
(info_ptr->valid & PNG_INFO_pHYs) != 0)
1015
{
1016
if (res_x != NULL)
1017
{
1018
*res_x = info_ptr->x_pixels_per_unit;
1019
retval |= PNG_INFO_pHYs;
1020
}
1021
1022
if (res_y != NULL)
1023
{
1024
*res_y = info_ptr->y_pixels_per_unit;
1025
retval |= PNG_INFO_pHYs;
1026
}
1027
1028
if (unit_type != NULL)
1029
{
1030
*unit_type = (int)info_ptr->phys_unit_type;
1031
retval |= PNG_INFO_pHYs;
1032
}
1033
}
1034
1035
return (retval);
1036
}
1037
#endif /* pHYs */
1038
1039
png_uint_32 PNGAPI
1040
png_get_PLTE(png_const_structrp png_ptr, png_inforp info_ptr,
1041
png_colorp *palette, int *num_palette)
1042
{
1043
png_debug1(1, "in %s retrieval function", "PLTE");
1044
1045
if (png_ptr != NULL && info_ptr != NULL &&
1046
(info_ptr->valid & PNG_INFO_PLTE) != 0 && palette != NULL)
1047
{
1048
*palette = info_ptr->palette;
1049
*num_palette = info_ptr->num_palette;
1050
png_debug1(3, "num_palette = %d", *num_palette);
1051
return (PNG_INFO_PLTE);
1052
}
1053
1054
return (0);
1055
}
1056
1057
#ifdef PNG_sBIT_SUPPORTED
1058
png_uint_32 PNGAPI
1059
png_get_sBIT(png_const_structrp png_ptr, png_inforp info_ptr,
1060
png_color_8p *sig_bit)
1061
{
1062
png_debug1(1, "in %s retrieval function", "sBIT");
1063
1064
if (png_ptr != NULL && info_ptr != NULL &&
1065
(info_ptr->valid & PNG_INFO_sBIT) != 0 && sig_bit != NULL)
1066
{
1067
*sig_bit = &(info_ptr->sig_bit);
1068
return (PNG_INFO_sBIT);
1069
}
1070
1071
return (0);
1072
}
1073
#endif
1074
1075
#ifdef PNG_TEXT_SUPPORTED
1076
int PNGAPI
1077
png_get_text(png_const_structrp png_ptr, png_inforp info_ptr,
1078
png_textp *text_ptr, int *num_text)
1079
{
1080
if (png_ptr != NULL && info_ptr != NULL && info_ptr->num_text > 0)
1081
{
1082
png_debug1(1, "in 0x%lx retrieval function",
1083
(unsigned long)png_ptr->chunk_name);
1084
1085
if (text_ptr != NULL)
1086
*text_ptr = info_ptr->text;
1087
1088
if (num_text != NULL)
1089
*num_text = info_ptr->num_text;
1090
1091
return info_ptr->num_text;
1092
}
1093
1094
if (num_text != NULL)
1095
*num_text = 0;
1096
1097
return(0);
1098
}
1099
#endif
1100
1101
#ifdef PNG_tIME_SUPPORTED
1102
png_uint_32 PNGAPI
1103
png_get_tIME(png_const_structrp png_ptr, png_inforp info_ptr,
1104
png_timep *mod_time)
1105
{
1106
png_debug1(1, "in %s retrieval function", "tIME");
1107
1108
if (png_ptr != NULL && info_ptr != NULL &&
1109
(info_ptr->valid & PNG_INFO_tIME) != 0 && mod_time != NULL)
1110
{
1111
*mod_time = &(info_ptr->mod_time);
1112
return (PNG_INFO_tIME);
1113
}
1114
1115
return (0);
1116
}
1117
#endif
1118
1119
#ifdef PNG_tRNS_SUPPORTED
1120
png_uint_32 PNGAPI
1121
png_get_tRNS(png_const_structrp png_ptr, png_inforp info_ptr,
1122
png_bytep *trans_alpha, int *num_trans, png_color_16p *trans_color)
1123
{
1124
png_uint_32 retval = 0;
1125
if (png_ptr != NULL && info_ptr != NULL &&
1126
(info_ptr->valid & PNG_INFO_tRNS) != 0)
1127
{
1128
png_debug1(1, "in %s retrieval function", "tRNS");
1129
1130
if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
1131
{
1132
if (trans_alpha != NULL)
1133
{
1134
*trans_alpha = info_ptr->trans_alpha;
1135
retval |= PNG_INFO_tRNS;
1136
}
1137
1138
if (trans_color != NULL)
1139
*trans_color = &(info_ptr->trans_color);
1140
}
1141
1142
else /* if (info_ptr->color_type != PNG_COLOR_TYPE_PALETTE) */
1143
{
1144
if (trans_color != NULL)
1145
{
1146
*trans_color = &(info_ptr->trans_color);
1147
retval |= PNG_INFO_tRNS;
1148
}
1149
1150
if (trans_alpha != NULL)
1151
*trans_alpha = NULL;
1152
}
1153
1154
if (num_trans != NULL)
1155
{
1156
*num_trans = info_ptr->num_trans;
1157
retval |= PNG_INFO_tRNS;
1158
}
1159
}
1160
1161
return (retval);
1162
}
1163
#endif
1164
1165
#ifdef PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED
1166
int PNGAPI
1167
png_get_unknown_chunks(png_const_structrp png_ptr, png_inforp info_ptr,
1168
png_unknown_chunkpp unknowns)
1169
{
1170
if (png_ptr != NULL && info_ptr != NULL && unknowns != NULL)
1171
{
1172
*unknowns = info_ptr->unknown_chunks;
1173
return info_ptr->unknown_chunks_num;
1174
}
1175
1176
return (0);
1177
}
1178
#endif
1179
1180
#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
1181
png_byte PNGAPI
1182
png_get_rgb_to_gray_status (png_const_structrp png_ptr)
1183
{
1184
return (png_byte)(png_ptr ? png_ptr->rgb_to_gray_status : 0);
1185
}
1186
#endif
1187
1188
#ifdef PNG_USER_CHUNKS_SUPPORTED
1189
png_voidp PNGAPI
1190
png_get_user_chunk_ptr(png_const_structrp png_ptr)
1191
{
1192
return (png_ptr ? png_ptr->user_chunk_ptr : NULL);
1193
}
1194
#endif
1195
1196
size_t PNGAPI
1197
png_get_compression_buffer_size(png_const_structrp png_ptr)
1198
{
1199
if (png_ptr == NULL)
1200
return 0;
1201
1202
#ifdef PNG_WRITE_SUPPORTED
1203
if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0)
1204
#endif
1205
{
1206
#ifdef PNG_SEQUENTIAL_READ_SUPPORTED
1207
return png_ptr->IDAT_read_size;
1208
#else
1209
return PNG_IDAT_READ_SIZE;
1210
#endif
1211
}
1212
1213
#ifdef PNG_WRITE_SUPPORTED
1214
else
1215
return png_ptr->zbuffer_size;
1216
#endif
1217
}
1218
1219
#ifdef PNG_SET_USER_LIMITS_SUPPORTED
1220
/* These functions were added to libpng 1.2.6 and were enabled
1221
* by default in libpng-1.4.0 */
1222
png_uint_32 PNGAPI
1223
png_get_user_width_max (png_const_structrp png_ptr)
1224
{
1225
return (png_ptr ? png_ptr->user_width_max : 0);
1226
}
1227
1228
png_uint_32 PNGAPI
1229
png_get_user_height_max (png_const_structrp png_ptr)
1230
{
1231
return (png_ptr ? png_ptr->user_height_max : 0);
1232
}
1233
1234
/* This function was added to libpng 1.4.0 */
1235
png_uint_32 PNGAPI
1236
png_get_chunk_cache_max (png_const_structrp png_ptr)
1237
{
1238
return (png_ptr ? png_ptr->user_chunk_cache_max : 0);
1239
}
1240
1241
/* This function was added to libpng 1.4.1 */
1242
png_alloc_size_t PNGAPI
1243
png_get_chunk_malloc_max (png_const_structrp png_ptr)
1244
{
1245
return (png_ptr ? png_ptr->user_chunk_malloc_max : 0);
1246
}
1247
#endif /* SET_USER_LIMITS */
1248
1249
/* These functions were added to libpng 1.4.0 */
1250
#ifdef PNG_IO_STATE_SUPPORTED
1251
png_uint_32 PNGAPI
1252
png_get_io_state (png_const_structrp png_ptr)
1253
{
1254
return png_ptr->io_state;
1255
}
1256
1257
png_uint_32 PNGAPI
1258
png_get_io_chunk_type (png_const_structrp png_ptr)
1259
{
1260
return png_ptr->chunk_name;
1261
}
1262
#endif /* IO_STATE */
1263
1264
#ifdef PNG_CHECK_FOR_INVALID_INDEX_SUPPORTED
1265
# ifdef PNG_GET_PALETTE_MAX_SUPPORTED
1266
int PNGAPI
1267
png_get_palette_max(png_const_structp png_ptr, png_const_infop info_ptr)
1268
{
1269
if (png_ptr != NULL && info_ptr != NULL)
1270
return png_ptr->num_palette_max;
1271
1272
return (-1);
1273
}
1274
# endif
1275
#endif
1276
1277
#endif /* READ || WRITE */
1278
1279