update libpng
update libpng, the repo now requires a vcpkg setup for integrating but skipping the install step should allow it to work for windows an linux, mac might need more
9
Engine/lib/lpng/contrib/.editorconfig
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
# https://editorconfig.org
|
||||
|
||||
root = false
|
||||
|
||||
[*.[ch]]
|
||||
indent_size = unset
|
||||
indent_style = unset
|
||||
max_doc_length = unset
|
||||
max_line_length = unset
|
||||
|
|
@ -1,3 +1,5 @@
|
|||
External contributions to libpng
|
||||
--------------------------------
|
||||
|
||||
This "contrib" directory contains contributions which are not necessarily under
|
||||
the libpng license, although all are open source. They are not part of
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@
|
|||
*
|
||||
* Copyright (c) 2014 Glenn Randers-Pehrson
|
||||
* Written by John Bowler, 2014.
|
||||
* Last changed in libpng 1.6.10 [March 6, 2014]
|
||||
*
|
||||
* This code is released under the libpng license.
|
||||
* For conditions of distribution and use, see the disclaimer
|
||||
|
|
@ -24,6 +23,7 @@
|
|||
* has been compiled only, not linked: no version of the library has been found,
|
||||
* only the header files exist in the NDK.
|
||||
*/
|
||||
|
||||
#include <cpu-features.h>
|
||||
|
||||
static int
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@
|
|||
*
|
||||
* Copyright (c) 2014 Glenn Randers-Pehrson
|
||||
* Written by Mans Rullgard, 2011.
|
||||
* Last changed in libpng 1.6.10 [March 6, 2014]
|
||||
*
|
||||
* This code is released under the libpng license.
|
||||
* For conditions of distribution and use, see the disclaimer
|
||||
|
|
@ -22,6 +21,7 @@
|
|||
* This generic __linux__ implementation requires reading /proc/self/auxv and
|
||||
* looking at each element for one that records NEON capabilities.
|
||||
*/
|
||||
|
||||
#include <unistd.h> /* for POSIX 1003.1 */
|
||||
#include <errno.h> /* for EINTR */
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
/* contrib/arm-neon/linux.c
|
||||
*
|
||||
* Last changed in libpng 1.6.31 [July 27, 2017]
|
||||
* Copyright (c) 2014, 2017 Glenn Randers-Pehrson
|
||||
* Written by John Bowler, 2014, 2017.
|
||||
*
|
||||
|
|
@ -19,6 +18,7 @@
|
|||
* This code is strict ANSI-C and is probably moderately portable; it does
|
||||
* however use <stdio.h> and it assumes that /proc/cpuinfo is never localized.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
static int
|
||||
|
|
|
|||
133
Engine/lib/lpng/contrib/conftest/basic.dfa
Normal file
|
|
@ -0,0 +1,133 @@
|
|||
# basic.dfa
|
||||
# Build time configuration of libpng
|
||||
#
|
||||
# Author: John Bowler
|
||||
# Copyright: (c) John Bowler, 2024
|
||||
# Usage rights:
|
||||
# To the extent possible under law, the author has waived all copyright and
|
||||
# related or neighboring rights to this work. This work is published from:
|
||||
# United States.
|
||||
#
|
||||
# Build libpng with basic read and write support. This enables the lowest
|
||||
# level libpng read and write APIs - the "row-by-row" ones.
|
||||
#
|
||||
# Support is enabled only for those transformations that are observed to be
|
||||
# required by widely used apps or are in the v3 specification.
|
||||
#
|
||||
|
||||
everything = off
|
||||
|
||||
# The sequential read code is enabled here; the progressive code can be used
|
||||
# instead but there is no point enabling both.
|
||||
|
||||
option READ on
|
||||
option SEQUENTIAL_READ on
|
||||
option EASY_ACCESS on
|
||||
option SET_USER_LIMITS on
|
||||
option INFO_IMAGE on
|
||||
option READ_16BIT on
|
||||
|
||||
# Errors: these can be disabled but then there won't be any error messages
|
||||
# just failures and the error messages are really needed for apps:
|
||||
option WARNINGS on
|
||||
option ERROR_TEXT on
|
||||
option BENIGN_READ_ERRORS on
|
||||
|
||||
# Required for many display programs such as web browsers:
|
||||
option PROGRESSIVE_READ on
|
||||
|
||||
# Switch on the write code - this makes a minimalist encoder but with
|
||||
# interlace support turned on; otherwise png_read_png..png_write_png will
|
||||
# fail on an interlaced image.
|
||||
option WRITE on
|
||||
option WRITE_INTERLACING on
|
||||
option WRITE_16BIT on
|
||||
|
||||
# Usages of the 'fixed' APIs are relatively rare but they do occur
|
||||
# one or the other for both the API and the internal math.
|
||||
|
||||
#Fixed point:
|
||||
option FIXED_POINT on
|
||||
|
||||
#Floating point:
|
||||
option FLOATING_POINT on
|
||||
option FLOATING_ARITHMETIC on
|
||||
|
||||
# Basic error handling, IO and user memory support. The latter allows the
|
||||
# application program to provide its own implementations of 'malloc' and 'free'.
|
||||
option SETJMP on
|
||||
option STDIO on
|
||||
option USER_MEM on
|
||||
|
||||
# Gamma handling: this needs to be on for the gamma handling
|
||||
option READ_GAMMA on
|
||||
|
||||
# The supported chunks
|
||||
chunk bKGD on
|
||||
chunk cHRM on
|
||||
chunk eXIf on
|
||||
chunk gAMA on
|
||||
chunk iCCP on
|
||||
chunk iTXt on
|
||||
chunk pHYs on
|
||||
chunk sBIT on
|
||||
chunk sRGB on
|
||||
chunk tEXt on
|
||||
chunk tIME on
|
||||
chunk tRNS on
|
||||
chunk zTXt on
|
||||
|
||||
# These don't seem to be used anywhere:
|
||||
# chunk pCAL
|
||||
# chunk sCAL
|
||||
# chunk sPLT
|
||||
|
||||
# The rest of this is app dependent: none of these options are required for
|
||||
# read/write of the full range of PNG files and the normal chunk handling on
|
||||
# read.
|
||||
option WRITE_CUSTOMIZE_ZTXT_COMPRESSION on
|
||||
option WRITE_CUSTOMIZE_COMPRESSION on
|
||||
|
||||
option READ_EXPAND on
|
||||
option READ_FILLER on
|
||||
option READ_GRAY_TO_RGB on
|
||||
option READ_INVERT on
|
||||
option READ_PACK on
|
||||
option READ_RGB_TO_GRAY on
|
||||
option READ_SCALE_16_TO_8 on
|
||||
option READ_SHIFT on
|
||||
option READ_STRIP_16_TO_8 on
|
||||
option READ_STRIP_ALPHA on
|
||||
option READ_SWAP on
|
||||
|
||||
option CONVERT_tIME on
|
||||
|
||||
# optipng
|
||||
option IO_STATE on
|
||||
option STORE_UNKNOWN_CHUNKS on
|
||||
option HANDLE_AS_UNKNOWN on
|
||||
|
||||
# pngcrush
|
||||
option READ_USER_TRANSFORM on
|
||||
option WRITE_FLUSH on
|
||||
|
||||
# pnmtopng
|
||||
chunk hIST on
|
||||
|
||||
# cairo
|
||||
option WRITE_PACKSWAP on
|
||||
option WRITE_USER_TRANSFORM on
|
||||
|
||||
# graphicsmagick
|
||||
option READ_USER_CHUNKS on
|
||||
|
||||
# Qt5.15 qtgui (gentoo package split) Qt6.6 qtbase
|
||||
option READ_BGR on
|
||||
option WRITE_BGR on
|
||||
option READ_SWAP_ALPHA on
|
||||
option WRITE_SWAP_ALPHA on
|
||||
chunk oFFs on
|
||||
|
||||
# ghostscript-gpl
|
||||
option WRITE_INVERT_ALPHA on
|
||||
option WRITE_INVERT on
|
||||
15
Engine/lib/lpng/contrib/conftest/fixed.dfa
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
# fixed.dfa
|
||||
# Build time configuration of libpng
|
||||
#
|
||||
# Author: John Bowler
|
||||
# Copyright: (c) John Bowler, 2025
|
||||
# Usage rights:
|
||||
# To the extent possible under law, the author has waived all copyright and
|
||||
# related or neighboring rights to this work. This work is published from:
|
||||
# United States.
|
||||
#
|
||||
# Test the standard libpng configuration without floating point (the internal
|
||||
# fixed point implementations are used instead).
|
||||
#
|
||||
option FLOATING_ARITHMETIC off
|
||||
option FLOATING_POINT off
|
||||
14
Engine/lib/lpng/contrib/conftest/float-fixed.dfa
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
# fixed-float.dfa
|
||||
# Build time configuration of libpng
|
||||
#
|
||||
# Author: John Bowler
|
||||
# Copyright: (c) John Bowler, 2025
|
||||
# Usage rights:
|
||||
# To the extent possible under law, the author has waived all copyright and
|
||||
# related or neighboring rights to this work. This work is published from:
|
||||
# United States.
|
||||
#
|
||||
# Test the standard libpng configuration with the fixed point internal
|
||||
# implementation in place of the default floating point
|
||||
#
|
||||
option FLOATING_ARITHMETIC off
|
||||
21
Engine/lib/lpng/contrib/conftest/nocompile-limits.dfa
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
# nolimits.dfa
|
||||
# Build time configuration of libpng
|
||||
#
|
||||
# Author: John Bowler
|
||||
# Copyright: (c) John Bowler, 2025
|
||||
#
|
||||
# Usage rights:
|
||||
# To the extent possible under law, the author has waived all copyright and
|
||||
# related or neighboring rights to this work. This work is published from:
|
||||
# United States.
|
||||
#
|
||||
# Build libpng without any limits and without run-time settable limits. Turning
|
||||
# USER_LIMITS off reduces libpng code size by allowing compile-time elimination
|
||||
# of some checking code.
|
||||
#
|
||||
option USER_LIMITS off
|
||||
|
||||
@# define PNG_USER_WIDTH_MAX PNG_UINT_31_MAX
|
||||
@# define PNG_USER_HEIGHT_MAX PNG_UINT_31_MAX
|
||||
@# define PNG_USER_CHUNK_CACHE_MAX 0
|
||||
@# define PNG_USER_CHUNK_MALLOC_MAX 0
|
||||
19
Engine/lib/lpng/contrib/conftest/nolimits.dfa
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
# nolimits.dfa
|
||||
# Build time configuration of libpng
|
||||
#
|
||||
# Author: John Bowler
|
||||
# Copyright: (c) John Bowler, 2025
|
||||
#
|
||||
# Usage rights:
|
||||
# To the extent possible under law, the author has waived all copyright and
|
||||
# related or neighboring rights to this work. This work is published from:
|
||||
# United States.
|
||||
#
|
||||
# Build libpng without any limits. With these settigs run-time limits are still
|
||||
# possible.
|
||||
#
|
||||
@# define PNG_USER_WIDTH_MAX PNG_UINT_31_MAX
|
||||
@# define PNG_USER_HEIGHT_MAX PNG_UINT_31_MAX
|
||||
@# define PNG_USER_CHUNK_CACHE_MAX 0
|
||||
@# define PNG_USER_CHUNK_MALLOC_MAX 0
|
||||
|
||||
13
Engine/lib/lpng/contrib/conftest/read-full.dfa
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
# read-full.dfa
|
||||
# Build time configuration of libpng
|
||||
#
|
||||
# Author: John Bowler
|
||||
# Copyright: (c) John Bowler, 2025
|
||||
# Usage rights:
|
||||
# To the extent possible under law, the author has waived all copyright and
|
||||
# related or neighboring rights to this work. This work is published from:
|
||||
# United States.
|
||||
#
|
||||
# Build libpng with no write support and full read support.
|
||||
#
|
||||
option WRITE off
|
||||
13
Engine/lib/lpng/contrib/conftest/write-full.dfa
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
# write-full.dfa
|
||||
# Build time configuration of libpng
|
||||
#
|
||||
# Author: John Bowler
|
||||
# Copyright: (c) John Bowler, 2025
|
||||
# Usage rights:
|
||||
# To the extent possible under law, the author has waived all copyright and
|
||||
# related or neighboring rights to this work. This work is published from:
|
||||
# United States.
|
||||
#
|
||||
# Build libpng with no read support and full write support.
|
||||
#
|
||||
option READ off
|
||||
143
Engine/lib/lpng/contrib/examples/.clang-format
Normal file
|
|
@ -0,0 +1,143 @@
|
|||
---
|
||||
Language: Cpp
|
||||
AccessModifierOffset: -3
|
||||
AlignAfterOpenBracket: Align
|
||||
AlignArrayOfStructures: None
|
||||
AlignConsecutiveAssignments:
|
||||
Enabled: false
|
||||
AlignConsecutiveBitFields:
|
||||
Enabled: false
|
||||
AlignConsecutiveDeclarations:
|
||||
Enabled: false
|
||||
AlignConsecutiveMacros:
|
||||
Enabled: false
|
||||
AlignConsecutiveShortCaseStatements:
|
||||
Enabled: false
|
||||
AlignEscapedNewlines: DontAlign
|
||||
AlignOperands: false
|
||||
AlignTrailingComments:
|
||||
Kind: Never
|
||||
OverEmptyLines: 0
|
||||
AllowAllArgumentsOnNextLine: true
|
||||
AllowAllParametersOfDeclarationOnNextLine: true
|
||||
AllowBreakBeforeNoexceptSpecifier: Never
|
||||
AllowShortBlocksOnASingleLine: Never
|
||||
AllowShortCaseExpressionOnASingleLine: true
|
||||
AllowShortCaseLabelsOnASingleLine: true
|
||||
AllowShortCompoundRequirementOnASingleLine: true
|
||||
AllowShortEnumsOnASingleLine: false
|
||||
AllowShortFunctionsOnASingleLine: None
|
||||
AllowShortIfStatementsOnASingleLine: Never
|
||||
AllowShortLambdasOnASingleLine: All
|
||||
AllowShortLoopsOnASingleLine: false
|
||||
AllowShortNamespacesOnASingleLine: false
|
||||
AlwaysBreakBeforeMultilineStrings: false
|
||||
BinPackArguments: true
|
||||
BinPackParameters: BinPack
|
||||
BitFieldColonSpacing: Both
|
||||
BraceWrapping:
|
||||
AfterCaseLabel: true
|
||||
AfterClass: true
|
||||
AfterControlStatement: Always
|
||||
AfterEnum: true
|
||||
AfterExternBlock: false
|
||||
AfterFunction: true
|
||||
AfterNamespace: false
|
||||
AfterObjCDeclaration: true
|
||||
AfterStruct: true
|
||||
AfterUnion: true
|
||||
BeforeCatch: true
|
||||
BeforeElse: true
|
||||
BeforeLambdaBody: false
|
||||
BeforeWhile: false
|
||||
IndentBraces: false
|
||||
SplitEmptyFunction: true
|
||||
SplitEmptyRecord: true
|
||||
SplitEmptyNamespace: true
|
||||
BreakAdjacentStringLiterals: true
|
||||
BreakAfterAttributes: Leave
|
||||
BreakAfterJavaFieldAnnotations: false
|
||||
BreakAfterReturnType: TopLevel
|
||||
BreakArrays: true
|
||||
BreakBeforeBinaryOperators: None
|
||||
BreakBeforeConceptDeclarations: Always
|
||||
BreakBeforeBraces: Custom
|
||||
BreakBeforeTernaryOperators: false
|
||||
BreakStringLiterals: false
|
||||
BreakTemplateDeclarations: MultiLine
|
||||
ColumnLimit: 79
|
||||
ContinuationIndentWidth: 3
|
||||
DerivePointerAlignment: true
|
||||
EmptyLineAfterAccessModifier: Never
|
||||
EmptyLineBeforeAccessModifier: LogicalBlock
|
||||
FixNamespaceComments: true
|
||||
IncludeBlocks: Preserve
|
||||
IndentAccessModifiers: false
|
||||
IndentCaseBlocks: true
|
||||
IndentCaseLabels: true
|
||||
IndentExportBlock: true
|
||||
IndentExternBlock: AfterExternBlock
|
||||
IndentGotoLabels: false
|
||||
IndentPPDirectives: None
|
||||
IndentRequiresClause: true
|
||||
IndentWidth: 3
|
||||
IndentWrappedFunctionNames: false
|
||||
KeepEmptyLines:
|
||||
AtEndOfFile: false
|
||||
AtStartOfBlock: false
|
||||
AtStartOfFile: false
|
||||
KeepFormFeed: false
|
||||
MaxEmptyLinesToKeep: 2
|
||||
NamespaceIndentation: None
|
||||
PackConstructorInitializers: Never
|
||||
PointerAlignment: Left
|
||||
QualifierAlignment: Custom
|
||||
QualifierOrder: [static, inline, constexpr, const, volatile, restrict, type]
|
||||
ReferenceAlignment: Pointer
|
||||
ReflowComments: Never
|
||||
RequiresClausePosition: OwnLine
|
||||
RequiresExpressionIndentation: OuterScope
|
||||
SortIncludes: false
|
||||
SortUsingDeclarations: LexicographicNumeric
|
||||
SpaceAfterCStyleCast: false
|
||||
SpaceAfterLogicalNot: false
|
||||
SpaceAfterTemplateKeyword: true
|
||||
SpaceAroundPointerQualifiers: Default
|
||||
SpaceBeforeAssignmentOperators: true
|
||||
SpaceBeforeCaseColon: false
|
||||
SpaceBeforeCpp11BracedList: false
|
||||
SpaceBeforeCtorInitializerColon: true
|
||||
SpaceBeforeInheritanceColon: true
|
||||
SpaceBeforeJsonColon: false
|
||||
SpaceBeforeParens: ControlStatements
|
||||
SpaceBeforeParensOptions:
|
||||
AfterControlStatements: true
|
||||
AfterFunctionDefinitionName: false
|
||||
AfterFunctionDeclarationName: false
|
||||
AfterOverloadedOperator: false
|
||||
AfterPlacementOperator: true
|
||||
AfterRequiresInClause: false
|
||||
AfterRequiresInExpression: false
|
||||
BeforeNonEmptyParentheses: false
|
||||
SpaceBeforeRangeBasedForLoopColon: true
|
||||
SpaceBeforeSquareBrackets: false
|
||||
SpaceInEmptyBlock: false
|
||||
SpacesBeforeTrailingComments: 1
|
||||
SpacesInAngles: Never
|
||||
SpacesInContainerLiterals: true
|
||||
SpacesInLineCommentPrefix:
|
||||
Minimum: 1
|
||||
Maximum: -1
|
||||
SpacesInParens: Never
|
||||
SpacesInParensOptions:
|
||||
ExceptDoubleParentheses: false
|
||||
InCStyleCasts: false
|
||||
InConditionalStatements: false
|
||||
InEmptyParentheses: false
|
||||
Other: false
|
||||
SpacesInSquareBrackets: false
|
||||
Standard: Latest
|
||||
TabWidth: 8
|
||||
UseTab: Never
|
||||
WrapNamespaceBodyWithEmptyLines: Leave
|
||||
...
|
||||
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
This directory (contrib/examples) contains examples of libpng usage.
|
||||
|
||||
NO COPYRIGHT RIGHTS ARE CLAIMED TO ANY OF THE FILES IN THIS DIRECTORY.
|
||||
|
|
|
|||
|
|
@ -26,8 +26,9 @@
|
|||
|
||||
#include <png.h>
|
||||
|
||||
#if defined(PNG_READ_SUPPORTED) && defined(PNG_STDIO_SUPPORTED) && \
|
||||
defined (PNG_iCCP_SUPPORTED)
|
||||
#if !defined(PNG_iCCP_SUPPORTED) || !defined(PNG_READ_SUPPORTED)
|
||||
#error This program requires libpng supporting the iCCP chunk and the read API
|
||||
#endif
|
||||
|
||||
|
||||
static int verbose = 1;
|
||||
|
|
@ -36,7 +37,8 @@ static png_byte no_profile[] = "no profile";
|
|||
static png_bytep
|
||||
extract(FILE *fp, png_uint_32 *proflen)
|
||||
{
|
||||
png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,0,0,0);
|
||||
png_structp png_ptr =
|
||||
png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
|
||||
png_infop info_ptr = NULL;
|
||||
png_bytep result = NULL;
|
||||
|
||||
|
|
@ -69,7 +71,7 @@ extract(FILE *fp, png_uint_32 *proflen)
|
|||
png_bytep profile;
|
||||
|
||||
if (png_get_iCCP(png_ptr, info_ptr, &name, &compression_type, &profile,
|
||||
proflen) & PNG_INFO_iCCP)
|
||||
proflen) & PNG_INFO_iCCP)
|
||||
{
|
||||
result = malloc(*proflen);
|
||||
if (result != NULL)
|
||||
|
|
@ -80,7 +82,7 @@ extract(FILE *fp, png_uint_32 *proflen)
|
|||
}
|
||||
|
||||
else
|
||||
result = no_profile;
|
||||
result = no_profile;
|
||||
}
|
||||
|
||||
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
|
||||
|
|
@ -107,7 +109,7 @@ extract_one_file(const char *filename)
|
|||
const char *ep = strrchr(filename, '.');
|
||||
|
||||
if (ep != NULL)
|
||||
len = ep-filename;
|
||||
len = ep - filename;
|
||||
|
||||
else
|
||||
len = strlen(filename);
|
||||
|
|
@ -119,14 +121,14 @@ extract_one_file(const char *filename)
|
|||
FILE *of;
|
||||
|
||||
memcpy(output, filename, len);
|
||||
strcpy(output+len, ".icc");
|
||||
strcpy(output + len, ".icc");
|
||||
|
||||
of = fopen(output, "wb");
|
||||
if (of != NULL)
|
||||
{
|
||||
if (fwrite(profile, proflen, 1, of) == 1 &&
|
||||
fflush(of) == 0 &&
|
||||
fclose(of) == 0)
|
||||
fflush(of) == 0 &&
|
||||
fclose(of) == 0)
|
||||
{
|
||||
if (verbose)
|
||||
printf("%s -> %s\n", filename, output);
|
||||
|
|
@ -155,12 +157,15 @@ extract_one_file(const char *filename)
|
|||
}
|
||||
|
||||
else if (verbose && profile == no_profile)
|
||||
printf("%s has no profile\n", filename);
|
||||
printf("%s has no profile\n", filename);
|
||||
}
|
||||
|
||||
else
|
||||
fprintf(stderr, "%s: could not open file\n", filename);
|
||||
|
||||
if (fp != NULL)
|
||||
fclose(fp);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
@ -170,7 +175,7 @@ main(int argc, char **argv)
|
|||
int i;
|
||||
int extracted = 0;
|
||||
|
||||
for (i=1; i<argc; ++i)
|
||||
for (i = 1; i < argc; ++i)
|
||||
{
|
||||
if (strcmp(argv[i], "-q") == 0)
|
||||
verbose = 0;
|
||||
|
|
@ -182,4 +187,3 @@ main(int argc, char **argv)
|
|||
/* Exit code is true if any extract succeeds */
|
||||
return extracted == 0;
|
||||
}
|
||||
#endif /* READ && STDIO && iCCP */
|
||||
|
|
|
|||
|
|
@ -15,8 +15,8 @@
|
|||
* images. Normally you would call png_set_interlace_handling() to have libpng
|
||||
* deal with the interlace for you, but that obliges you to buffer half of the
|
||||
* image to assemble the interlaced rows. In this code
|
||||
* png_set_interlace_handling() is not called and, instead, the code handles the
|
||||
* interlace passes directly looking for the required pixel.
|
||||
* png_set_interlace_handling() is not called and, instead, the code handles
|
||||
* the interlace passes directly looking for the required pixel.
|
||||
*/
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
|
@ -27,34 +27,37 @@
|
|||
*/
|
||||
#include "../../png.h"
|
||||
|
||||
#if defined(PNG_READ_SUPPORTED) && defined(PNG_SEQUENTIAL_READ_SUPPORTED)
|
||||
#if !defined(PNG_READ_SUPPORTED) || !defined(PNG_SEQUENTIAL_READ_SUPPORTED)
|
||||
#error This program requires libpng supporting the read and sequential read API
|
||||
#endif
|
||||
|
||||
|
||||
/* Return component 'c' of pixel 'x' from the given row. */
|
||||
static unsigned int
|
||||
component(png_const_bytep row, png_uint_32 x, unsigned int c,
|
||||
unsigned int bit_depth, unsigned int channels)
|
||||
unsigned int bit_depth, unsigned int channels)
|
||||
{
|
||||
/* PNG images can be up to 2^31 pixels wide, but this means they can be up to
|
||||
* 2^37 bits wide (for a 64-bit pixel - the largest possible) and hence 2^34
|
||||
* bytes wide. Since the row fitted into memory, however, the following must
|
||||
/* PNG images can be up to 2^31 pixels wide, which means they can be up to
|
||||
* 2^37 bits wide (for a 64-bit pixel - the largest possible) and hence
|
||||
* 2^34 bytes wide. Since the row fitted into memory, the following must
|
||||
* work:
|
||||
*/
|
||||
png_uint_32 bit_offset_hi = bit_depth * ((x >> 6) * channels);
|
||||
png_uint_32 bit_offset_lo = bit_depth * ((x & 0x3f) * channels + c);
|
||||
|
||||
row = (png_const_bytep)(((const png_byte (*)[8])row) + bit_offset_hi);
|
||||
row = (png_const_bytep)(((const png_byte(*)[8])row) + bit_offset_hi);
|
||||
row += bit_offset_lo >> 3;
|
||||
bit_offset_lo &= 0x07;
|
||||
|
||||
/* PNG pixels are packed into bytes to put the first pixel in the highest
|
||||
* bits of the byte and into two bytes for 16-bit values with the high 8 bits
|
||||
* first, so:
|
||||
* bits of the byte, and into two bytes for 16-bit values with the high
|
||||
* 8 bits first, so:
|
||||
*/
|
||||
switch (bit_depth)
|
||||
{
|
||||
case 1: return (row[0] >> (7-bit_offset_lo)) & 0x01;
|
||||
case 2: return (row[0] >> (6-bit_offset_lo)) & 0x03;
|
||||
case 4: return (row[0] >> (4-bit_offset_lo)) & 0x0f;
|
||||
case 1: return (row[0] >> (7 - bit_offset_lo)) & 0x01;
|
||||
case 2: return (row[0] >> (6 - bit_offset_lo)) & 0x03;
|
||||
case 4: return (row[0] >> (4 - bit_offset_lo)) & 0x0f;
|
||||
case 8: return row[0];
|
||||
case 16: return (row[0] << 8) + row[1];
|
||||
default:
|
||||
|
|
@ -71,7 +74,7 @@ component(png_const_bytep row, png_uint_32 x, unsigned int c,
|
|||
*/
|
||||
static void
|
||||
print_pixel(png_structp png_ptr, png_infop info_ptr, png_const_bytep row,
|
||||
png_uint_32 x)
|
||||
png_uint_32 x)
|
||||
{
|
||||
unsigned int bit_depth = png_get_bit_depth(png_ptr, info_ptr);
|
||||
|
||||
|
|
@ -92,22 +95,24 @@ print_pixel(png_structp png_ptr, png_infop info_ptr, png_const_bytep row,
|
|||
int num_palette = 0;
|
||||
|
||||
if ((png_get_PLTE(png_ptr, info_ptr, &palette, &num_palette) &
|
||||
PNG_INFO_PLTE) && num_palette > 0 && palette != NULL)
|
||||
PNG_INFO_PLTE) &&
|
||||
(num_palette > 0) &&
|
||||
(palette != NULL))
|
||||
{
|
||||
png_bytep trans_alpha = NULL;
|
||||
int num_trans = 0;
|
||||
if ((png_get_tRNS(png_ptr, info_ptr, &trans_alpha, &num_trans,
|
||||
NULL) & PNG_INFO_tRNS) && num_trans > 0 &&
|
||||
trans_alpha != NULL)
|
||||
NULL) & PNG_INFO_tRNS) &&
|
||||
(num_trans > 0) &&
|
||||
(trans_alpha != NULL))
|
||||
printf("INDEXED %u = %d %d %d %d\n", index,
|
||||
palette[index].red, palette[index].green,
|
||||
palette[index].blue,
|
||||
index < num_trans ? trans_alpha[index] : 255);
|
||||
palette[index].red, palette[index].green,
|
||||
palette[index].blue,
|
||||
index < num_trans ? trans_alpha[index] : 255);
|
||||
|
||||
else /* no transparency */
|
||||
printf("INDEXED %u = %d %d %d\n", index,
|
||||
palette[index].red, palette[index].green,
|
||||
palette[index].blue);
|
||||
printf("INDEXED %u = %d %d %d\n", index, palette[index].red,
|
||||
palette[index].green, palette[index].blue);
|
||||
}
|
||||
|
||||
else
|
||||
|
|
@ -117,20 +122,20 @@ print_pixel(png_structp png_ptr, png_infop info_ptr, png_const_bytep row,
|
|||
|
||||
case PNG_COLOR_TYPE_RGB:
|
||||
printf("RGB %u %u %u\n", component(row, x, 0, bit_depth, 3),
|
||||
component(row, x, 1, bit_depth, 3),
|
||||
component(row, x, 2, bit_depth, 3));
|
||||
component(row, x, 1, bit_depth, 3),
|
||||
component(row, x, 2, bit_depth, 3));
|
||||
return;
|
||||
|
||||
case PNG_COLOR_TYPE_GRAY_ALPHA:
|
||||
printf("GRAY+ALPHA %u %u\n", component(row, x, 0, bit_depth, 2),
|
||||
component(row, x, 1, bit_depth, 2));
|
||||
component(row, x, 1, bit_depth, 2));
|
||||
return;
|
||||
|
||||
case PNG_COLOR_TYPE_RGB_ALPHA:
|
||||
printf("RGBA %u %u %u %u\n", component(row, x, 0, bit_depth, 4),
|
||||
component(row, x, 1, bit_depth, 4),
|
||||
component(row, x, 2, bit_depth, 4),
|
||||
component(row, x, 3, bit_depth, 4));
|
||||
component(row, x, 1, bit_depth, 4),
|
||||
component(row, x, 2, bit_depth, 4),
|
||||
component(row, x, 3, bit_depth, 4));
|
||||
return;
|
||||
|
||||
default:
|
||||
|
|
@ -138,7 +143,8 @@ print_pixel(png_structp png_ptr, png_infop info_ptr, png_const_bytep row,
|
|||
}
|
||||
}
|
||||
|
||||
int main(int argc, const char **argv)
|
||||
int
|
||||
main(int argc, const char **argv)
|
||||
{
|
||||
/* This program uses the default, <setjmp.h> based, libpng error handling
|
||||
* mechanism, therefore any local variable that exists before the call to
|
||||
|
|
@ -146,7 +152,7 @@ int main(int argc, const char **argv)
|
|||
* be declared with 'volatile' to ensure that their values don't get
|
||||
* destroyed by longjmp:
|
||||
*/
|
||||
volatile int result = 1/*fail*/;
|
||||
volatile int result = 1 /*fail*/;
|
||||
|
||||
if (argc == 4)
|
||||
{
|
||||
|
|
@ -163,8 +169,8 @@ int main(int argc, const char **argv)
|
|||
* writes error messages to stderr. Creating the png_struct is a
|
||||
* little tricky; just copy the following code.
|
||||
*/
|
||||
png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,
|
||||
NULL, NULL, NULL);
|
||||
png_structp png_ptr =
|
||||
png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
|
||||
|
||||
if (png_ptr != NULL)
|
||||
{
|
||||
|
|
@ -184,11 +190,11 @@ int main(int argc, const char **argv)
|
|||
compression_method, filter_method;
|
||||
png_bytep row_tmp;
|
||||
|
||||
/* Now associate the recently opened (FILE*) with the default
|
||||
* libpng initialization functions. Sometimes libpng is
|
||||
* compiled without stdio support (it can be difficult to do
|
||||
* in some environments); in that case you will have to write
|
||||
* your own read callback to read data from the (FILE*).
|
||||
/* Now associate the recently opened FILE object with the
|
||||
* default libpng initialization functions. Sometimes libpng
|
||||
* is compiled without stdio support (it can be difficult to
|
||||
* do in some environments); in that case you will have to
|
||||
* write your own read callback to read data from the stream.
|
||||
*/
|
||||
png_init_io(png_ptr, f);
|
||||
|
||||
|
|
@ -202,21 +208,21 @@ int main(int argc, const char **argv)
|
|||
* space. In this case png_malloc is used - it will not
|
||||
* return if memory isn't available.
|
||||
*/
|
||||
row = png_malloc(png_ptr, png_get_rowbytes(png_ptr,
|
||||
info_ptr));
|
||||
row =
|
||||
png_malloc(png_ptr, png_get_rowbytes(png_ptr, info_ptr));
|
||||
|
||||
/* To avoid the overhead of using a volatile auto copy row_tmp
|
||||
/* Avoid the overhead of using a volatile auto copy row_tmp
|
||||
* to a local here - just use row for the png_free below.
|
||||
*/
|
||||
row_tmp = row;
|
||||
|
||||
/* All the information we need is in the header is returned by
|
||||
* png_get_IHDR, if this fails we can now use 'png_error' to
|
||||
/* All the information we need is in the header returned by
|
||||
* png_get_IHDR. If this fails, we can use 'png_error' to
|
||||
* signal the error and return control to the setjmp above.
|
||||
*/
|
||||
if (png_get_IHDR(png_ptr, info_ptr, &width, &height,
|
||||
&bit_depth, &color_type, &interlace_method,
|
||||
&compression_method, &filter_method))
|
||||
&bit_depth, &color_type, &interlace_method,
|
||||
&compression_method, &filter_method))
|
||||
{
|
||||
int passes, pass;
|
||||
|
||||
|
|
@ -242,7 +248,7 @@ int main(int argc, const char **argv)
|
|||
/* Now read the pixels, pass-by-pass, row-by-row: */
|
||||
png_start_read_image(png_ptr);
|
||||
|
||||
for (pass=0; pass<passes; ++pass)
|
||||
for (pass = 0; pass < passes; ++pass)
|
||||
{
|
||||
png_uint_32 ystart, xstart, ystep, xstep;
|
||||
png_uint_32 py;
|
||||
|
|
@ -299,19 +305,27 @@ int main(int argc, const char **argv)
|
|||
* are, of course, much better ways of doing this
|
||||
* than using a for loop:
|
||||
*/
|
||||
if (y == py) for (px = xstart, ppx = 0;
|
||||
px < width; px += xstep, ++ppx) if (x == px)
|
||||
if (y == py)
|
||||
{
|
||||
/* 'ppx' is the index of the pixel in the row
|
||||
* buffer.
|
||||
*/
|
||||
print_pixel(png_ptr, info_ptr, row_tmp, ppx);
|
||||
for (px = xstart, ppx = 0;
|
||||
px < width;
|
||||
px += xstep, ++ppx)
|
||||
{
|
||||
if (x == px)
|
||||
{
|
||||
/* 'ppx' is the index of the pixel in the
|
||||
* row buffer.
|
||||
*/
|
||||
print_pixel(png_ptr, info_ptr, row_tmp,
|
||||
ppx);
|
||||
|
||||
/* Now terminate the loops early - we have
|
||||
* found and handled the required data.
|
||||
*/
|
||||
goto pass_loop_end;
|
||||
} /* x loop */
|
||||
/* Now terminate the loops early - we have
|
||||
* found and handled the required data.
|
||||
*/
|
||||
goto pass_loop_end;
|
||||
} /* x loop */
|
||||
}
|
||||
}
|
||||
} /* y loop */
|
||||
} /* pass loop */
|
||||
|
||||
|
|
@ -323,7 +337,6 @@ int main(int argc, const char **argv)
|
|||
|
||||
else
|
||||
png_error(png_ptr, "pngpixel: png_get_IHDR failed");
|
||||
|
||||
}
|
||||
|
||||
else
|
||||
|
|
@ -349,7 +362,8 @@ int main(int argc, const char **argv)
|
|||
}
|
||||
|
||||
else
|
||||
fprintf(stderr, "pngpixel: out of memory allocating png_info\n");
|
||||
fprintf(stderr,
|
||||
"pngpixel: out of memory allocating png_info\n");
|
||||
|
||||
png_destroy_read_struct(&png_ptr, NULL, NULL);
|
||||
}
|
||||
|
|
@ -368,4 +382,3 @@ int main(int argc, const char **argv)
|
|||
|
||||
return result;
|
||||
}
|
||||
#endif /* READ && SEQUENTIAL_READ */
|
||||
|
|
|
|||
|
|
@ -5,13 +5,11 @@
|
|||
* related or neighboring rights to this work. This work is published from:
|
||||
* United States.
|
||||
*
|
||||
* Last changed in libpng 1.6.29 [March 16, 2017]
|
||||
*
|
||||
* Read a PNG and write it out in a fixed format, using the 'simplified API'
|
||||
* that was introduced in libpng-1.6.0.
|
||||
*
|
||||
* This sample code is just the code from the top of 'example.c' with some error
|
||||
* handling added. See example.c for more comments.
|
||||
* This sample code is just the code from 'example.c' with some error handling
|
||||
* added. See example.c in the top-level libpng directory for more comments.
|
||||
*/
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
|
|
@ -22,10 +20,15 @@
|
|||
* ensure the code picks up the local libpng implementation:
|
||||
*/
|
||||
#include "../../png.h"
|
||||
#if defined(PNG_SIMPLIFIED_READ_SUPPORTED) && \
|
||||
defined(PNG_SIMPLIFIED_WRITE_SUPPORTED)
|
||||
|
||||
int main(int argc, const char **argv)
|
||||
#if !defined(PNG_SIMPLIFIED_READ_SUPPORTED) || \
|
||||
!defined(PNG_SIMPLIFIED_WRITE_SUPPORTED)
|
||||
#error This program requires libpng supporting the simplified read/write API
|
||||
#endif
|
||||
|
||||
|
||||
int
|
||||
main(int argc, const char **argv)
|
||||
{
|
||||
int result = 1;
|
||||
|
||||
|
|
@ -50,22 +53,22 @@ int main(int argc, const char **argv)
|
|||
|
||||
if (buffer != NULL)
|
||||
{
|
||||
if (png_image_finish_read(&image, NULL/*background*/, buffer,
|
||||
0/*row_stride*/, NULL/*colormap for PNG_FORMAT_FLAG_COLORMAP */))
|
||||
if (png_image_finish_read(&image, NULL /*background*/, buffer,
|
||||
0 /*row_stride*/, NULL /*colormap */))
|
||||
{
|
||||
if (png_image_write_to_file(&image, argv[2],
|
||||
0/*convert_to_8bit*/, buffer, 0/*row_stride*/,
|
||||
NULL/*colormap*/))
|
||||
if (png_image_write_to_file(
|
||||
&image, argv[2], 0 /*convert_to_8bit*/, buffer,
|
||||
0 /*row_stride*/, NULL /*colormap*/))
|
||||
result = 0;
|
||||
|
||||
else
|
||||
fprintf(stderr, "pngtopng: write %s: %s\n", argv[2],
|
||||
image.message);
|
||||
image.message);
|
||||
}
|
||||
|
||||
else
|
||||
fprintf(stderr, "pngtopng: read %s: %s\n", argv[1],
|
||||
image.message);
|
||||
image.message);
|
||||
|
||||
free(buffer);
|
||||
}
|
||||
|
|
@ -73,7 +76,7 @@ int main(int argc, const char **argv)
|
|||
else
|
||||
{
|
||||
fprintf(stderr, "pngtopng: out of memory: %lu bytes\n",
|
||||
(unsigned long)PNG_IMAGE_SIZE(image));
|
||||
(unsigned long)PNG_IMAGE_SIZE(image));
|
||||
|
||||
/* This is the only place where a 'free' is required; libpng does
|
||||
* the cleanup on error and success, but in this case we couldn't
|
||||
|
|
@ -95,4 +98,3 @@ int main(int argc, const char **argv)
|
|||
|
||||
return result;
|
||||
}
|
||||
#endif /* READ && WRITE */
|
||||
|
|
|
|||
|
|
@ -6,9 +6,9 @@
|
|||
* United States.
|
||||
*
|
||||
* Read several PNG files, which should have an alpha channel or transparency
|
||||
* information, and composite them together to produce one or more 16-bit linear
|
||||
* RGBA intermediates. This involves doing the correct 'over' composition to
|
||||
* combine the alpha channels and corresponding data.
|
||||
* information, and composite them together to produce one or more 16-bit
|
||||
* linear RGBA intermediates. This involves doing the 'over' compositing
|
||||
* operation to combine the alpha channels and corresponding data.
|
||||
*
|
||||
* Finally read an output (background) PNG using the 24-bit RGB format (the
|
||||
* PNG will be composited on green (#00ff00) by default if it has an alpha
|
||||
|
|
@ -28,8 +28,8 @@
|
|||
* correctly. Apart from the libpng Simplified API the only work done in here
|
||||
* is to combine multiple input PNG images into a single sprite; this involves
|
||||
* a Porter-Duff 'over' operation and the input PNG images may, as a result,
|
||||
* be regarded as being layered one on top of the other with the first (leftmost
|
||||
* on the command line) being at the bottom and the last on the top.
|
||||
* be regarded as being layered one on top of the other with the first
|
||||
* (leftmost on the command line) being at the bottom and the last on the top.
|
||||
*/
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
|
|
@ -44,54 +44,61 @@
|
|||
*/
|
||||
#include "../../png.h"
|
||||
|
||||
#ifdef PNG_SIMPLIFIED_READ_SUPPORTED
|
||||
#if !defined(PNG_SIMPLIFIED_READ_SUPPORTED)
|
||||
#error This program requires libpng supporting the simplified read API
|
||||
#endif
|
||||
|
||||
#define sprite_name_chars 15
|
||||
struct sprite {
|
||||
FILE *file;
|
||||
png_uint_16p buffer;
|
||||
unsigned int width;
|
||||
unsigned int height;
|
||||
char name[sprite_name_chars+1];
|
||||
struct sprite
|
||||
{
|
||||
FILE *file;
|
||||
png_uint_16p buffer;
|
||||
unsigned int width;
|
||||
unsigned int height;
|
||||
char name[sprite_name_chars + 1];
|
||||
};
|
||||
|
||||
#if 0 /* div by 65535 test program */
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
|
||||
int main(void) {
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
double err = 0;
|
||||
unsigned int xerr = 0;
|
||||
unsigned int r = 32769;
|
||||
unsigned int x = 0;
|
||||
|
||||
do
|
||||
{
|
||||
unsigned int x = 0;
|
||||
unsigned int t = x + (x >> 16) /*+ (x >> 31)*/ + r;
|
||||
double v = x, errtest;
|
||||
|
||||
do {
|
||||
unsigned int t = x + (x >> 16) /*+ (x >> 31)*/ + r;
|
||||
double v = x, errtest;
|
||||
if (t < x)
|
||||
{
|
||||
fprintf(stderr, "overflow: %u+%u -> %u\n", x, r, t);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (t < x) {
|
||||
fprintf(stderr, "overflow: %u+%u -> %u\n", x, r, t);
|
||||
return 1;
|
||||
v /= 65535;
|
||||
errtest = v;
|
||||
t >>= 16;
|
||||
errtest -= t;
|
||||
|
||||
if (errtest > err)
|
||||
{
|
||||
err = errtest;
|
||||
xerr = x;
|
||||
|
||||
if (errtest >= .5)
|
||||
{
|
||||
fprintf(stderr, "error: %u/65535 = %f, not %u, error %f\n",
|
||||
x, v, t, errtest);
|
||||
return 0;
|
||||
}
|
||||
|
||||
v /= 65535;
|
||||
errtest = v;
|
||||
t >>= 16;
|
||||
errtest -= t;
|
||||
|
||||
if (errtest > err) {
|
||||
err = errtest;
|
||||
xerr = x;
|
||||
|
||||
if (errtest >= .5) {
|
||||
fprintf(stderr, "error: %u/65535 = %f, not %u, error %f\n",
|
||||
x, v, t, errtest);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
} while (++x <= 65535U*65535U);
|
||||
}
|
||||
}
|
||||
} while (++x <= 65535U * 65535U);
|
||||
|
||||
printf("error %f @ %u\n", err, xerr);
|
||||
|
||||
|
|
@ -101,7 +108,7 @@ int main(void) {
|
|||
|
||||
static void
|
||||
sprite_op(const struct sprite *sprite, int x_offset, int y_offset,
|
||||
png_imagep image, const png_uint_16 *buffer)
|
||||
png_imagep image, const png_uint_16 *buffer)
|
||||
{
|
||||
/* This is where the Porter-Duff 'Over' operator is evaluated; change this
|
||||
* code to change the operator (this could be parameterized). Any other
|
||||
|
|
@ -112,8 +119,8 @@ sprite_op(const struct sprite *sprite, int x_offset, int y_offset,
|
|||
/* Check for an x or y offset that pushes any part of the image beyond the
|
||||
* right or bottom of the sprite:
|
||||
*/
|
||||
if ((y_offset < 0 || (unsigned)/*SAFE*/y_offset < sprite->height) &&
|
||||
(x_offset < 0 || (unsigned)/*SAFE*/x_offset < sprite->width))
|
||||
if ((y_offset < 0 || /*SAFE*/ (unsigned)y_offset < sprite->height) &&
|
||||
(x_offset < 0 || /*SAFE*/ (unsigned)x_offset < sprite->width))
|
||||
{
|
||||
unsigned int y = 0;
|
||||
|
||||
|
|
@ -130,7 +137,7 @@ sprite_op(const struct sprite *sprite, int x_offset, int y_offset,
|
|||
do
|
||||
{
|
||||
/* In and out are RGBA values, so: */
|
||||
const png_uint_16 *in_pixel = buffer + (y * image->width + x)*4;
|
||||
const png_uint_16 *in_pixel = buffer + (y * image->width + x) * 4;
|
||||
png_uint_32 in_alpha = in_pixel[3];
|
||||
|
||||
/* This is the optimized Porter-Duff 'Over' operation, when the
|
||||
|
|
@ -139,10 +146,10 @@ sprite_op(const struct sprite *sprite, int x_offset, int y_offset,
|
|||
if (in_alpha > 0)
|
||||
{
|
||||
png_uint_16 *out_pixel = sprite->buffer +
|
||||
((y+y_offset) * sprite->width + (x+x_offset))*4;
|
||||
((y + y_offset) * sprite->width + (x + x_offset)) * 4;
|
||||
|
||||
/* This is the weight to apply to the output: */
|
||||
in_alpha = 65535-in_alpha;
|
||||
in_alpha = 65535 - in_alpha;
|
||||
|
||||
if (in_alpha > 0)
|
||||
{
|
||||
|
|
@ -159,9 +166,9 @@ sprite_op(const struct sprite *sprite, int x_offset, int y_offset,
|
|||
*/
|
||||
png_uint_32 tmp;
|
||||
|
||||
# define compose(c)\
|
||||
tmp = out_pixel[c] * in_alpha;\
|
||||
tmp = (tmp + (tmp >> 16) + 32769) >> 16;\
|
||||
# define compose(c) \
|
||||
tmp = out_pixel[c] * in_alpha; \
|
||||
tmp = (tmp + (tmp >> 16) + 32769) >> 16; \
|
||||
out_pixel[c] = tmp + in_pixel[c]
|
||||
|
||||
/* The following is very vectorizable... */
|
||||
|
|
@ -172,15 +179,15 @@ sprite_op(const struct sprite *sprite, int x_offset, int y_offset,
|
|||
}
|
||||
|
||||
else
|
||||
out_pixel[0] = in_pixel[0],
|
||||
out_pixel[1] = in_pixel[1],
|
||||
out_pixel[2] = in_pixel[2],
|
||||
{
|
||||
out_pixel[0] = in_pixel[0];
|
||||
out_pixel[1] = in_pixel[1];
|
||||
out_pixel[2] = in_pixel[2];
|
||||
out_pixel[3] = in_pixel[3];
|
||||
}
|
||||
}
|
||||
}
|
||||
while (++x < image->width);
|
||||
}
|
||||
while (++y < image->height);
|
||||
} while (++x < image->width);
|
||||
} while (++y < image->height);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -224,9 +231,8 @@ create_sprite(struct sprite *sprite, int *argc, const char ***argv)
|
|||
|
||||
if (buffer != NULL)
|
||||
{
|
||||
if (png_image_finish_read(&image, NULL/*background*/, buffer,
|
||||
0/*row_stride*/,
|
||||
NULL/*colormap for PNG_FORMAT_FLAG_COLORMAP*/))
|
||||
if (png_image_finish_read(&image, NULL /*background*/, buffer,
|
||||
0 /*row_stride*/, NULL /*colormap*/))
|
||||
{
|
||||
/* This is the place where the Porter-Duff 'Over' operator
|
||||
* needs to be done by this code. In fact, any image
|
||||
|
|
@ -245,14 +251,14 @@ create_sprite(struct sprite *sprite, int *argc, const char ***argv)
|
|||
{
|
||||
free(buffer);
|
||||
fprintf(stderr, "simpleover: read %s: %s\n", (*argv)[0],
|
||||
image.message);
|
||||
image.message);
|
||||
}
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "simpleover: out of memory: %lu bytes\n",
|
||||
(unsigned long)PNG_IMAGE_SIZE(image));
|
||||
(unsigned long)PNG_IMAGE_SIZE(image));
|
||||
|
||||
/* png_image_free must be called if we abort the Simplified API
|
||||
* read because of a problem detected in this code. If problems
|
||||
|
|
@ -290,8 +296,9 @@ create_sprite(struct sprite *sprite, int *argc, const char ***argv)
|
|||
save.flags = PNG_IMAGE_FLAG_FAST;
|
||||
save.colormap_entries = 0;
|
||||
|
||||
if (png_image_write_to_stdio(&save, sprite->file, 1/*convert_to_8_bit*/,
|
||||
sprite->buffer, 0/*row_stride*/, NULL/*colormap*/))
|
||||
if (png_image_write_to_stdio(&save, sprite->file, 1 /*convert_to_8_bit*/,
|
||||
sprite->buffer, 0 /*row_stride*/,
|
||||
NULL /*colormap*/))
|
||||
{
|
||||
/* Success; the buffer is no longer needed: */
|
||||
free(sprite->buffer);
|
||||
|
|
@ -301,19 +308,20 @@ create_sprite(struct sprite *sprite, int *argc, const char ***argv)
|
|||
|
||||
else
|
||||
fprintf(stderr, "simpleover: write sprite %s: %s\n", sprite->name,
|
||||
save.message);
|
||||
save.message);
|
||||
}
|
||||
|
||||
else
|
||||
fprintf(stderr, "simpleover: sprite %s: could not allocate tmpfile: %s\n",
|
||||
sprite->name, strerror(errno));
|
||||
fprintf(stderr,
|
||||
"simpleover: sprite %s: could not allocate tmpfile: %s\n",
|
||||
sprite->name, strerror(errno));
|
||||
|
||||
return 0; /* fail */
|
||||
}
|
||||
|
||||
static int
|
||||
add_sprite(png_imagep output, png_bytep out_buf, struct sprite *sprite,
|
||||
int *argc, const char ***argv)
|
||||
int *argc, const char ***argv)
|
||||
{
|
||||
/* Given a --add argument naming this sprite, perform the operations listed
|
||||
* in the following arguments. The arguments are expected to have the form
|
||||
|
|
@ -334,13 +342,13 @@ add_sprite(png_imagep output, png_bytep out_buf, struct sprite *sprite,
|
|||
* will fit.
|
||||
*/
|
||||
if (x < 0 || y < 0 ||
|
||||
(unsigned)/*SAFE*/x >= output->width ||
|
||||
(unsigned)/*SAFE*/y >= output->height ||
|
||||
sprite->width > output->width-x ||
|
||||
sprite->height > output->height-y)
|
||||
/*SAFE*/ (unsigned)x >= output->width ||
|
||||
/*SAFE*/ (unsigned)y >= output->height ||
|
||||
sprite->width > output->width - x ||
|
||||
sprite->height > output->height - y)
|
||||
{
|
||||
fprintf(stderr, "simpleover: sprite %s @ (%d,%d) outside image\n",
|
||||
sprite->name, x, y);
|
||||
sprite->name, x, y);
|
||||
/* Could just skip this, but for the moment it is an error */
|
||||
return 0; /* error */
|
||||
}
|
||||
|
|
@ -359,10 +367,10 @@ add_sprite(png_imagep output, png_bytep out_buf, struct sprite *sprite,
|
|||
{
|
||||
in.format = PNG_FORMAT_RGB; /* force compose */
|
||||
|
||||
if (png_image_finish_read(&in, NULL/*background*/,
|
||||
out_buf + (y*output->width + x)*3/*RGB*/,
|
||||
output->width*3/*row_stride*/,
|
||||
NULL/*colormap for PNG_FORMAT_FLAG_COLORMAP*/))
|
||||
if (png_image_finish_read(
|
||||
&in, NULL /*background*/,
|
||||
out_buf + (y * output->width + x) * 3 /*RGB*/,
|
||||
output->width * 3 /*row_stride*/, NULL /*colormap*/))
|
||||
{
|
||||
++*argv, --*argc;
|
||||
continue;
|
||||
|
|
@ -371,7 +379,7 @@ add_sprite(png_imagep output, png_bytep out_buf, struct sprite *sprite,
|
|||
|
||||
/* The read failed: */
|
||||
fprintf(stderr, "simpleover: add sprite %s: %s\n", sprite->name,
|
||||
in.message);
|
||||
in.message);
|
||||
return 0; /* error */
|
||||
}
|
||||
}
|
||||
|
|
@ -379,7 +387,7 @@ add_sprite(png_imagep output, png_bytep out_buf, struct sprite *sprite,
|
|||
else
|
||||
{
|
||||
fprintf(stderr, "simpleover: --add='%s': invalid position %s\n",
|
||||
sprite->name, (*argv)[0]);
|
||||
sprite->name, (*argv)[0]);
|
||||
return 0; /* error */
|
||||
}
|
||||
}
|
||||
|
|
@ -389,10 +397,10 @@ add_sprite(png_imagep output, png_bytep out_buf, struct sprite *sprite,
|
|||
|
||||
static int
|
||||
simpleover_process(png_imagep output, png_bytep out_buf, int argc,
|
||||
const char **argv)
|
||||
const char **argv)
|
||||
{
|
||||
int result = 1; /* success */
|
||||
# define csprites 10/*limit*/
|
||||
# define csprites 10 /*limit*/
|
||||
# define str(a) #a
|
||||
int nsprites = 0;
|
||||
struct sprite sprites[csprites];
|
||||
|
|
@ -412,23 +420,25 @@ simpleover_process(png_imagep output, png_bytep out_buf, int argc,
|
|||
sprites[nsprites].width = sprites[nsprites].height = 0;
|
||||
sprites[nsprites].name[0] = 0;
|
||||
|
||||
n = sscanf(argv[0], "--sprite=%u,%u,%" str(sprite_name_chars) "s%c",
|
||||
&sprites[nsprites].width, &sprites[nsprites].height,
|
||||
sprites[nsprites].name, &tombstone);
|
||||
n = sscanf(argv[0],
|
||||
"--sprite=%u,%u,%" str(sprite_name_chars) "s%c",
|
||||
&sprites[nsprites].width, &sprites[nsprites].height,
|
||||
sprites[nsprites].name, &tombstone);
|
||||
|
||||
if ((n == 2 || n == 3) &&
|
||||
sprites[nsprites].width > 0 && sprites[nsprites].height > 0)
|
||||
(sprites[nsprites].width > 0) &&
|
||||
(sprites[nsprites].height > 0))
|
||||
{
|
||||
size_t buf_size, tmp;
|
||||
|
||||
/* Default a name if not given. */
|
||||
if (sprites[nsprites].name[0] == 0)
|
||||
sprintf(sprites[nsprites].name, "sprite-%d", nsprites+1);
|
||||
sprintf(sprites[nsprites].name, "sprite-%d", nsprites + 1);
|
||||
|
||||
/* Allocate a buffer for the sprite and calculate the buffer
|
||||
* size:
|
||||
*/
|
||||
buf_size = sizeof (png_uint_16 [4]);
|
||||
buf_size = sizeof(png_uint_16[4]);
|
||||
buf_size *= sprites[nsprites].width;
|
||||
buf_size *= sprites[nsprites].height;
|
||||
|
||||
|
|
@ -437,7 +447,7 @@ simpleover_process(png_imagep output, png_bytep out_buf, int argc,
|
|||
tmp /= sprites[nsprites].width;
|
||||
tmp /= sprites[nsprites].height;
|
||||
|
||||
if (tmp == sizeof (png_uint_16 [4]))
|
||||
if (tmp == sizeof(png_uint_16[4]))
|
||||
{
|
||||
sprites[nsprites].buffer = malloc(buf_size);
|
||||
/* This buffer must be initialized to transparent: */
|
||||
|
|
@ -448,7 +458,7 @@ simpleover_process(png_imagep output, png_bytep out_buf, int argc,
|
|||
sprites[nsprites].file = NULL;
|
||||
++argv, --argc;
|
||||
|
||||
if (create_sprite(sprites+nsprites++, &argc, &argv))
|
||||
if (create_sprite(sprites + nsprites++, &argc, &argv))
|
||||
{
|
||||
result = 1; /* still ok */
|
||||
continue;
|
||||
|
|
@ -466,7 +476,8 @@ simpleover_process(png_imagep output, png_bytep out_buf, int argc,
|
|||
else
|
||||
{
|
||||
fprintf(stderr, "simpleover: %s: invalid sprite (%u,%u)\n",
|
||||
argv[0], sprites[nsprites].width, sprites[nsprites].height);
|
||||
argv[0],
|
||||
sprites[nsprites].width, sprites[nsprites].height);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -480,7 +491,7 @@ simpleover_process(png_imagep output, png_bytep out_buf, int argc,
|
|||
|
||||
else if (strncmp(argv[0], "--add=", 6) == 0)
|
||||
{
|
||||
const char *name = argv[0]+6;
|
||||
const char *name = argv[0] + 6;
|
||||
int isprite = nsprites;
|
||||
|
||||
++argv, --argc;
|
||||
|
|
@ -489,7 +500,8 @@ simpleover_process(png_imagep output, png_bytep out_buf, int argc,
|
|||
{
|
||||
if (strcmp(sprites[isprite].name, name) == 0)
|
||||
{
|
||||
if (!add_sprite(output, out_buf, sprites+isprite, &argc, &argv))
|
||||
if (!add_sprite(output, out_buf, sprites + isprite,
|
||||
&argc, &argv))
|
||||
goto out; /* error in add_sprite */
|
||||
|
||||
break;
|
||||
|
|
@ -498,7 +510,8 @@ simpleover_process(png_imagep output, png_bytep out_buf, int argc,
|
|||
|
||||
if (isprite < 0) /* sprite not found */
|
||||
{
|
||||
fprintf(stderr, "simpleover: --add='%s': sprite not found\n", name);
|
||||
fprintf(stderr, "simpleover: --add='%s': sprite not found\n",
|
||||
name);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -526,7 +539,8 @@ out:
|
|||
return result;
|
||||
}
|
||||
|
||||
int main(int argc, const char **argv)
|
||||
int
|
||||
main(int argc, const char **argv)
|
||||
{
|
||||
int result = 1; /* default to fail */
|
||||
|
||||
|
|
@ -536,7 +550,7 @@ int main(int argc, const char **argv)
|
|||
const char *output = NULL;
|
||||
png_image image;
|
||||
|
||||
if (argc > 2 && argv[2][0] != '-'/*an operation*/)
|
||||
if (argc > 2 && argv[2][0] != '-' /*an operation*/)
|
||||
{
|
||||
output = argv[2];
|
||||
argi = 3;
|
||||
|
|
@ -558,7 +572,7 @@ int main(int argc, const char **argv)
|
|||
png_color background = {0, 0xff, 0}; /* fully saturated green */
|
||||
|
||||
if (png_image_finish_read(&image, &background, buffer,
|
||||
0/*row_stride*/, NULL/*colormap for PNG_FORMAT_FLAG_COLORMAP */))
|
||||
0 /*row_stride*/, NULL /*colormap*/))
|
||||
{
|
||||
/* At this point png_image_finish_read has cleaned up the
|
||||
* allocated data in png_image, and only the buffer needs to be
|
||||
|
|
@ -566,22 +580,24 @@ int main(int argc, const char **argv)
|
|||
*
|
||||
* Perform the remaining operations:
|
||||
*/
|
||||
if (simpleover_process(&image, buffer, argc-argi, argv+argi))
|
||||
if (simpleover_process(&image, buffer,
|
||||
argc - argi, argv + argi))
|
||||
{
|
||||
/* Write the output: */
|
||||
if ((output != NULL &&
|
||||
png_image_write_to_file(&image, output,
|
||||
0/*convert_to_8bit*/, buffer, 0/*row_stride*/,
|
||||
NULL/*colormap*/)) ||
|
||||
png_image_write_to_file(
|
||||
&image, output, 0 /*convert_to_8bit*/, buffer,
|
||||
0 /*row_stride*/, NULL /*colormap*/)) ||
|
||||
(output == NULL &&
|
||||
png_image_write_to_stdio(&image, stdout,
|
||||
0/*convert_to_8bit*/, buffer, 0/*row_stride*/,
|
||||
NULL/*colormap*/)))
|
||||
png_image_write_to_stdio(
|
||||
&image, stdout, 0 /*convert_to_8bit*/, buffer,
|
||||
0 /*row_stride*/, NULL /*colormap*/)))
|
||||
result = 0;
|
||||
|
||||
else
|
||||
fprintf(stderr, "simpleover: write %s: %s\n",
|
||||
output == NULL ? "stdout" : output, image.message);
|
||||
output == NULL ? "stdout" : output,
|
||||
image.message);
|
||||
}
|
||||
|
||||
/* else simpleover_process writes an error message */
|
||||
|
|
@ -589,7 +605,7 @@ int main(int argc, const char **argv)
|
|||
|
||||
else
|
||||
fprintf(stderr, "simpleover: read %s: %s\n", argv[1],
|
||||
image.message);
|
||||
image.message);
|
||||
|
||||
free(buffer);
|
||||
}
|
||||
|
|
@ -597,7 +613,7 @@ int main(int argc, const char **argv)
|
|||
else
|
||||
{
|
||||
fprintf(stderr, "simpleover: out of memory: %lu bytes\n",
|
||||
(unsigned long)PNG_IMAGE_SIZE(image));
|
||||
(unsigned long)PNG_IMAGE_SIZE(image));
|
||||
|
||||
/* This is the only place where a 'free' is required; libpng does
|
||||
* the cleanup on error and success, but in this case we couldn't
|
||||
|
|
@ -617,7 +633,8 @@ int main(int argc, const char **argv)
|
|||
else
|
||||
{
|
||||
/* Usage message */
|
||||
fprintf(stderr,
|
||||
fprintf(
|
||||
stderr,
|
||||
"simpleover: usage: simpleover background.png [output.png]\n"
|
||||
" Output 'background.png' as a 24-bit RGB PNG file in 'output.png'\n"
|
||||
" or, if not given, stdout. 'background.png' will be composited\n"
|
||||
|
|
@ -628,13 +645,13 @@ int main(int argc, const char **argv)
|
|||
" --sprite=width,height,name {[--at=x,y] {sprite.png}}\n"
|
||||
" Produce a transparent sprite of size (width,height) and with\n"
|
||||
" name 'name'.\n"
|
||||
" For each sprite.png composite it using a Porter-Duff 'Over'\n"
|
||||
" operation at offset (x,y) in the sprite (defaulting to (0,0)).\n"
|
||||
" For each sprite.png composite it is using a Porter-Duff 'Over'\n"
|
||||
" operation at offset (x,y) in the sprite, defaulting to (0,0).\n"
|
||||
" Input PNGs will be truncated to the area of the sprite.\n"
|
||||
"\n"
|
||||
" --add='name' {x,y}\n"
|
||||
" Optionally, before output, composite a sprite, 'name', which\n"
|
||||
" must have been previously produced using --sprite, at each\n"
|
||||
" must have been previously produced using --sprite at each\n"
|
||||
" offset (x,y) in the output image. Each sprite must fit\n"
|
||||
" completely within the output image.\n"
|
||||
"\n"
|
||||
|
|
@ -645,4 +662,3 @@ int main(int argc, const char **argv)
|
|||
|
||||
return result;
|
||||
}
|
||||
#endif /* SIMPLIFIED_READ */
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@
|
|||
- 1.10: added support for non-default visuals; fixed X pixel-conversion
|
||||
- 1.11: added extra set of parentheses to png_jmpbuf() macro; fixed
|
||||
command-line parsing bug
|
||||
- 1.12: fixed some small X memory leaks (thanks to François Petitjean)
|
||||
- 1.12: fixed some small X memory leaks (thanks to François Petitjean)
|
||||
- 1.13: fixed XFreeGC() crash bug (thanks to Patrick Welche)
|
||||
- 1.14: added support for X resources (thanks to Gerhard Niklasch)
|
||||
- 2.00: dual-licensed (added GNU GPL)
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@
|
|||
- 1.11: added -usleep option for demos; fixed command-line parsing bug
|
||||
- 1.12: added -pause option for demos and testing
|
||||
- 1.20: added runtime MMX-enabling/disabling and new -mmx* options
|
||||
- 1.21: fixed some small X memory leaks (thanks to François Petitjean)
|
||||
- 1.21: fixed some small X memory leaks (thanks to François Petitjean)
|
||||
- 1.22: fixed XFreeGC() crash bug (thanks to Patrick Welche)
|
||||
- 1.23: added -bgpat 0 mode (std white/gray checkerboard, 8x8 squares)
|
||||
- 1.30: added -loop option for -bgpat (ifdef FEATURE_LOOP); fixed bpp =
|
||||
|
|
|
|||
|
|
@ -2,8 +2,6 @@
|
|||
#
|
||||
# Copyright (c) 2013 John Cunningham Bowler
|
||||
#
|
||||
# Last changed in libpng 1.6.0 [February 14, 2013]
|
||||
#
|
||||
# This code is released under the libpng license.
|
||||
# For conditions of distribution and use, see the disclaimer
|
||||
# and license in png.h
|
||||
|
|
|
|||
|
|
@ -3,8 +3,6 @@
|
|||
/* Copyright: */
|
||||
#define COPYRIGHT "\251 2013,2015 John Cunningham Bowler"
|
||||
/*
|
||||
* Last changed in libpng 1.6.20 [November 24, 2015]
|
||||
*
|
||||
* This code is released under the libpng license.
|
||||
* For conditions of distribution and use, see the disclaimer
|
||||
* and license in png.h
|
||||
|
|
@ -299,25 +297,28 @@ generate_palette(png_colorp palette, png_bytep trans, int bit_depth,
|
|||
unsigned int x, y;
|
||||
volatile unsigned int ip = 0;
|
||||
|
||||
for (x=0; x<size; ++x) for (y=0; y<size; ++y)
|
||||
for (x=0; x<size; ++x)
|
||||
{
|
||||
ip = x + (size * y);
|
||||
for (y=0; y<size; ++y)
|
||||
{
|
||||
ip = x + (size * y);
|
||||
|
||||
/* size is at most 16, so the scaled value below fits in 16 bits
|
||||
*/
|
||||
# define interp(pos, c1, c2) ((pos * c1) + ((size-pos) * c2))
|
||||
# define xyinterp(x, y, c1, c2, c3, c4) (((size * size / 2) +\
|
||||
(interp(x, c1, c2) * y + (size-y) * interp(x, c3, c4))) /\
|
||||
(size*size))
|
||||
/* size is at most 16, so the scaled value below fits in 16 bits
|
||||
*/
|
||||
# define interp(pos, c1, c2) ((pos * c1) + ((size-pos) * c2))
|
||||
# define xyinterp(x, y, c1, c2, c3, c4) (((size * size / 2) +\
|
||||
(interp(x, c1, c2) * y + (size-y) * interp(x, c3, c4))) /\
|
||||
(size*size))
|
||||
|
||||
set_color(palette+ip, trans+ip,
|
||||
/* color: green, red,blue,white */
|
||||
xyinterp(x, y, 0, 255, 0, 255),
|
||||
xyinterp(x, y, 255, 0, 0, 255),
|
||||
xyinterp(x, y, 0, 0, 255, 255),
|
||||
/* alpha: 0, 102, 204, 255) */
|
||||
xyinterp(x, y, 0, 102, 204, 255),
|
||||
gamma_table);
|
||||
set_color(palette+ip, trans+ip,
|
||||
/* color: green, red,blue,white */
|
||||
xyinterp(x, y, 0, 255, 0, 255),
|
||||
xyinterp(x, y, 255, 0, 0, 255),
|
||||
xyinterp(x, y, 0, 0, 255, 255),
|
||||
/* alpha: 0, 102, 204, 255) */
|
||||
xyinterp(x, y, 0, 102, 204, 255),
|
||||
gamma_table);
|
||||
}
|
||||
}
|
||||
|
||||
return ip+1;
|
||||
|
|
@ -396,7 +397,7 @@ generate_row(png_bytep row, size_t rowbytes, unsigned int y, int color_type,
|
|||
image_size_of_type(color_type, bit_depth, colors, small)-1;
|
||||
png_uint_32 depth_max = (1U << bit_depth)-1; /* up to 65536 */
|
||||
|
||||
if (colors[0] == 0) if (small)
|
||||
if (colors[0] == 0 && small)
|
||||
{
|
||||
unsigned int pixel_depth = pixel_depth_of_type(color_type, bit_depth);
|
||||
|
||||
|
|
@ -495,7 +496,7 @@ generate_row(png_bytep row, size_t rowbytes, unsigned int y, int color_type,
|
|||
case 32:
|
||||
case 48:
|
||||
case 64:
|
||||
/* The rows are filled by an alogorithm similar to the above, in the
|
||||
/* The rows are filled by an algorithm similar to the above, in the
|
||||
* first row pixel bytes are all equal, increasing from 0 by 1 for
|
||||
* each pixel. In the second row the bytes within a pixel are
|
||||
* incremented 1,3,5,7,... from the previous row byte. Using an odd
|
||||
|
|
@ -858,10 +859,13 @@ write_png(const char **name, FILE *fp, int color_type, int bit_depth,
|
|||
{
|
||||
unsigned int i;
|
||||
|
||||
if (real_gamma == 45455) for (i=0; i<256; ++i)
|
||||
if (real_gamma == 45455)
|
||||
{
|
||||
gamma_table[i] = (png_byte)i;
|
||||
conv = 1.;
|
||||
for (i=0; i<256; ++i)
|
||||
{
|
||||
gamma_table[i] = (png_byte)i;
|
||||
conv = 1.;
|
||||
}
|
||||
}
|
||||
|
||||
else
|
||||
|
|
@ -1430,10 +1434,13 @@ find_parameters(png_const_charp what, png_charp param, png_charp *list,
|
|||
for (i=0; *param && i<nparams; ++i)
|
||||
{
|
||||
list[i] = param;
|
||||
while (*++param) if (*param == '\n' || *param == ':')
|
||||
while (*++param)
|
||||
{
|
||||
*param++ = 0; /* Terminate last parameter */
|
||||
break; /* And start a new one. */
|
||||
if (*param == '\n' || *param == ':')
|
||||
{
|
||||
*param++ = 0; /* Terminate last parameter */
|
||||
break; /* And start a new one. */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1869,7 +1876,7 @@ main(int argc, char **argv)
|
|||
}
|
||||
}
|
||||
|
||||
/* small and colors are incomparible (will probably crash if both are used at
|
||||
/* small and colors are incompatible (will probably crash if both are used at
|
||||
* the same time!)
|
||||
*/
|
||||
if (small && colors[0] != 0)
|
||||
|
|
|
|||
|
|
@ -1,9 +1,8 @@
|
|||
/* pngimage.c
|
||||
*
|
||||
* Copyright (c) 2021-2025 Cosmin Truta
|
||||
* Copyright (c) 2015,2016 John Cunningham Bowler
|
||||
*
|
||||
* Last changed in libpng 1.6.24 [August 4, 2016]
|
||||
*
|
||||
* This code is released under the libpng license.
|
||||
* For conditions of distribution and use, see the disclaimer
|
||||
* and license in png.h
|
||||
|
|
@ -12,6 +11,7 @@
|
|||
* using png_read_png and then write with png_write_png. Test all possible
|
||||
* transforms.
|
||||
*/
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
|
@ -39,7 +39,7 @@
|
|||
/* 1.6.1 added support for the configure test harness, which uses 77 to indicate
|
||||
* a skipped test, in earlier versions we need to succeed on a skipped test, so:
|
||||
*/
|
||||
#if PNG_LIBPNG_VER >= 10601 && defined(HAVE_CONFIG_H)
|
||||
#if defined(HAVE_CONFIG_H)
|
||||
# define SKIP 77
|
||||
#else
|
||||
# define SKIP 0
|
||||
|
|
@ -317,11 +317,10 @@ transform_name(int t)
|
|||
|
||||
t &= -t; /* first set bit */
|
||||
|
||||
for (i=0; i<TTABLE_SIZE; ++i) if (transform_info[i].name != NULL)
|
||||
{
|
||||
if ((transform_info[i].transform & t) != 0)
|
||||
return transform_info[i].name;
|
||||
}
|
||||
for (i=0; i<TTABLE_SIZE; ++i)
|
||||
if (transform_info[i].name != NULL)
|
||||
if ((transform_info[i].transform & t) != 0)
|
||||
return transform_info[i].name;
|
||||
|
||||
return "invalid transform";
|
||||
}
|
||||
|
|
@ -338,13 +337,16 @@ validate_T(void)
|
|||
{
|
||||
unsigned int i;
|
||||
|
||||
for (i=0; i<TTABLE_SIZE; ++i) if (transform_info[i].name != NULL)
|
||||
for (i=0; i<TTABLE_SIZE; ++i)
|
||||
{
|
||||
if (transform_info[i].when & TRANSFORM_R)
|
||||
read_transforms |= transform_info[i].transform;
|
||||
if (transform_info[i].name != NULL)
|
||||
{
|
||||
if (transform_info[i].when & TRANSFORM_R)
|
||||
read_transforms |= transform_info[i].transform;
|
||||
|
||||
if (transform_info[i].when & TRANSFORM_W)
|
||||
write_transforms |= transform_info[i].transform;
|
||||
if (transform_info[i].when & TRANSFORM_W)
|
||||
write_transforms |= transform_info[i].transform;
|
||||
}
|
||||
}
|
||||
|
||||
/* Reversible transforms are those which are supported on both read and
|
||||
|
|
@ -540,6 +542,7 @@ typedef enum
|
|||
struct display
|
||||
{
|
||||
jmp_buf error_return; /* Where to go to on error */
|
||||
error_level error_code; /* Set before longjmp */
|
||||
|
||||
const char *filename; /* The name of the original file */
|
||||
const char *operation; /* Operation being performed */
|
||||
|
|
@ -760,7 +763,10 @@ display_log(struct display *dp, error_level level, const char *fmt, ...)
|
|||
|
||||
/* Errors cause this routine to exit to the fail code */
|
||||
if (level > APP_FAIL || (level > ERRORS && !(dp->options & CONTINUE)))
|
||||
{
|
||||
dp->error_code = level;
|
||||
longjmp(dp->error_return, level);
|
||||
}
|
||||
}
|
||||
|
||||
/* error handler callbacks for libpng */
|
||||
|
|
@ -962,21 +968,24 @@ update_display(struct display *dp)
|
|||
int bd = dp->bit_depth;
|
||||
unsigned int i;
|
||||
|
||||
for (i=0; i<TTABLE_SIZE; ++i) if (transform_info[i].name != NULL)
|
||||
for (i=0; i<TTABLE_SIZE; ++i)
|
||||
{
|
||||
int transform = transform_info[i].transform;
|
||||
if (transform_info[i].name != NULL)
|
||||
{
|
||||
int transform = transform_info[i].transform;
|
||||
|
||||
if ((transform_info[i].valid_chunks == 0 ||
|
||||
(transform_info[i].valid_chunks & chunks) != 0) &&
|
||||
(transform_info[i].color_mask_required & ct) ==
|
||||
transform_info[i].color_mask_required &&
|
||||
(transform_info[i].color_mask_absent & ct) == 0 &&
|
||||
(transform_info[i].bit_depths & bd) != 0 &&
|
||||
(transform_info[i].when & TRANSFORM_R) != 0)
|
||||
active |= transform;
|
||||
if ((transform_info[i].valid_chunks == 0 ||
|
||||
(transform_info[i].valid_chunks & chunks) != 0) &&
|
||||
(transform_info[i].color_mask_required & ct) ==
|
||||
transform_info[i].color_mask_required &&
|
||||
(transform_info[i].color_mask_absent & ct) == 0 &&
|
||||
(transform_info[i].bit_depths & bd) != 0 &&
|
||||
(transform_info[i].when & TRANSFORM_R) != 0)
|
||||
active |= transform;
|
||||
|
||||
else if ((transform_info[i].when & TRANSFORM_R) != 0)
|
||||
inactive |= transform;
|
||||
else if ((transform_info[i].when & TRANSFORM_R) != 0)
|
||||
inactive |= transform;
|
||||
}
|
||||
}
|
||||
|
||||
/* Some transforms appear multiple times in the table; the 'active' status
|
||||
|
|
@ -1000,8 +1009,9 @@ compare_read(struct display *dp, int applied_transforms)
|
|||
int interlace_method, compression_method, filter_method;
|
||||
const char *e = NULL;
|
||||
|
||||
png_get_IHDR(dp->read_pp, dp->read_ip, &width, &height, &bit_depth,
|
||||
&color_type, &interlace_method, &compression_method, &filter_method);
|
||||
if (!png_get_IHDR(dp->read_pp, dp->read_ip, &width, &height, &bit_depth,
|
||||
&color_type, &interlace_method, &compression_method, &filter_method))
|
||||
display_log(dp, LIBPNG_BUG, "png_get_IHDR failed");
|
||||
|
||||
# define C(item) if (item != dp->item) \
|
||||
display_log(dp, APP_WARNING, "IHDR " #item "(%lu) changed to %lu",\
|
||||
|
|
@ -1012,7 +1022,12 @@ compare_read(struct display *dp, int applied_transforms)
|
|||
C(height);
|
||||
C(bit_depth);
|
||||
C(color_type);
|
||||
C(interlace_method);
|
||||
# ifdef PNG_WRITE_INTERLACING_SUPPORTED
|
||||
/* If write interlace has been disabled, the PNG file is still
|
||||
* written correctly, but as a regular (not-interlaced) PNG.
|
||||
*/
|
||||
C(interlace_method);
|
||||
# endif
|
||||
C(compression_method);
|
||||
C(filter_method);
|
||||
|
||||
|
|
@ -1081,8 +1096,9 @@ compare_read(struct display *dp, int applied_transforms)
|
|||
size_t x;
|
||||
|
||||
/* Find the first error */
|
||||
for (x=0; x<rowbytes-1; ++x) if (row[x] != orig[x])
|
||||
break;
|
||||
for (x=0; x<rowbytes-1; ++x)
|
||||
if (row[x] != orig[x])
|
||||
break;
|
||||
|
||||
display_log(dp, APP_FAIL,
|
||||
"byte(%lu,%lu) changed 0x%.2x -> 0x%.2x",
|
||||
|
|
@ -1137,6 +1153,7 @@ compare_read(struct display *dp, int applied_transforms)
|
|||
display_log(dp, LIBPNG_ERROR, "invalid colour type %d",
|
||||
color_type);
|
||||
/*NOTREACHED*/
|
||||
memset(sig_bits, 0, sizeof(sig_bits));
|
||||
bpp = 0;
|
||||
break;
|
||||
}
|
||||
|
|
@ -1198,7 +1215,7 @@ compare_read(struct display *dp, int applied_transforms)
|
|||
sig_bits[0] = (png_byte)b;
|
||||
break;
|
||||
|
||||
case 4: /* Relicate twice */
|
||||
case 4: /* Replicate twice */
|
||||
/* Value is 1, 2, 3 or 4 */
|
||||
b = 0xf & ((0xf << 4) >> sig_bits[0]);
|
||||
b |= b << 4;
|
||||
|
|
@ -1557,18 +1574,19 @@ static int
|
|||
do_test(struct display *dp, const char *file)
|
||||
/* Exists solely to isolate the setjmp clobbers */
|
||||
{
|
||||
int ret = setjmp(dp->error_return);
|
||||
dp->error_code = VERBOSE; /* The "lowest" level */
|
||||
|
||||
if (ret == 0)
|
||||
if (setjmp(dp->error_return) == 0)
|
||||
{
|
||||
test_one_file(dp, file);
|
||||
return 0;
|
||||
}
|
||||
|
||||
else if (ret < ERRORS) /* shouldn't longjmp on warnings */
|
||||
display_log(dp, INTERNAL_ERROR, "unexpected return code %d", ret);
|
||||
else if (dp->error_code < ERRORS) /* shouldn't longjmp on warnings */
|
||||
display_log(dp, INTERNAL_ERROR, "unexpected return code %d",
|
||||
dp->error_code);
|
||||
|
||||
return ret;
|
||||
return dp->error_code;
|
||||
}
|
||||
|
||||
int
|
||||
|
|
@ -1668,7 +1686,11 @@ main(int argc, char **argv)
|
|||
int ret = do_test(&d, argv[i]);
|
||||
|
||||
if (ret > QUIET) /* abort on user or internal error */
|
||||
{
|
||||
display_clean(&d);
|
||||
display_destroy(&d);
|
||||
return 99;
|
||||
}
|
||||
}
|
||||
|
||||
/* Here on any return, including failures, except user/internal issues
|
||||
|
|
@ -1686,8 +1708,9 @@ main(int argc, char **argv)
|
|||
|
||||
printf("%s: pngimage ", pass ? "PASS" : "FAIL");
|
||||
|
||||
for (j=1; j<option_end; ++j) if (j != ilog)
|
||||
printf("%s ", argv[j]);
|
||||
for (j=1; j<option_end; ++j)
|
||||
if (j != ilog)
|
||||
printf("%s ", argv[j]);
|
||||
|
||||
printf("%s\n", d.filename);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
/*-
|
||||
* pngstest.c
|
||||
/* pngstest.c
|
||||
*
|
||||
* Last changed in libpng 1.6.31 [July 27, 2017]
|
||||
* Copyright (c) 2021-2025 Cosmin Truta
|
||||
* Copyright (c) 2013-2017 John Cunningham Bowler
|
||||
*
|
||||
* This code is released under the libpng license.
|
||||
|
|
@ -10,8 +9,9 @@
|
|||
*
|
||||
* Test for the PNG 'simplified' APIs.
|
||||
*/
|
||||
|
||||
#define _ISOC90_SOURCE 1
|
||||
#define MALLOC_CHECK_ 2/*glibc facility: turn on debugging*/
|
||||
#define MALLOC_CHECK_ 2 /*glibc facility: turn on debugging*/
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
|
|
@ -37,7 +37,7 @@
|
|||
/* 1.6.1 added support for the configure test harness, which uses 77 to indicate
|
||||
* a skipped test, in earlier versions we need to succeed on a skipped test, so:
|
||||
*/
|
||||
#if PNG_LIBPNG_VER >= 10601 && defined(HAVE_CONFIG_H)
|
||||
#if defined(HAVE_CONFIG_H)
|
||||
# define SKIP 77
|
||||
#else
|
||||
# define SKIP 0
|
||||
|
|
@ -595,7 +595,8 @@ newimage(Image *image)
|
|||
memset(image, 0, sizeof *image);
|
||||
}
|
||||
|
||||
/* Reset the image to be read again - only needs to rewind the FILE* at present.
|
||||
/* Reset the image to be read again - only needs to rewind the FILE object at
|
||||
* present.
|
||||
*/
|
||||
static void
|
||||
resetimage(Image *image)
|
||||
|
|
@ -1150,7 +1151,7 @@ get_pixel(png_uint_32 format))(Pixel *p, png_const_voidp pb)
|
|||
*
|
||||
* 2) Remove color by mapping to grayscale. (Grayscale to color is a no-op.)
|
||||
*
|
||||
* 3) Convert between 8-bit and 16-bit components. (Both directtions are
|
||||
* 3) Convert between 8-bit and 16-bit components. (Both directions are
|
||||
* relevant.)
|
||||
*
|
||||
* This gives the following base format conversion matrix:
|
||||
|
|
@ -2701,7 +2702,7 @@ compare_two_images(Image *a, Image *b, int via_linear,
|
|||
{
|
||||
if ((a->opts & ACCUMULATE) == 0)
|
||||
{
|
||||
char pindex[9];
|
||||
char pindex[16];
|
||||
sprintf(pindex, "%lu[%lu]", (unsigned long)y,
|
||||
(unsigned long)a->image.colormap_entries);
|
||||
logerror(a, a->file_name, ": bad pixel index: ", pindex);
|
||||
|
|
@ -2712,12 +2713,12 @@ compare_two_images(Image *a, Image *b, int via_linear,
|
|||
else if (y >= b->image.colormap_entries)
|
||||
{
|
||||
if ((b->opts & ACCUMULATE) == 0)
|
||||
{
|
||||
char pindex[9];
|
||||
{
|
||||
char pindex[16];
|
||||
sprintf(pindex, "%lu[%lu]", (unsigned long)y,
|
||||
(unsigned long)b->image.colormap_entries);
|
||||
logerror(b, b->file_name, ": bad pixel index: ", pindex);
|
||||
}
|
||||
}
|
||||
result = 0;
|
||||
}
|
||||
|
||||
|
|
@ -2820,8 +2821,11 @@ compare_two_images(Image *a, Image *b, int via_linear,
|
|||
bchannels = component_loc(bloc, formatb);
|
||||
|
||||
/* Hence the btoa array. */
|
||||
for (i=0; i<4; ++i) if (bloc[i] < 4)
|
||||
btoa[bloc[i]] = aloc[i]; /* may be '4' for alpha */
|
||||
for (i=0; i<4; ++i)
|
||||
{
|
||||
if (bloc[i] < 4)
|
||||
btoa[bloc[i]] = aloc[i]; /* may be '4' for alpha */
|
||||
}
|
||||
|
||||
if (alpha_added)
|
||||
alpha_added = bloc[0]; /* location of alpha channel in image b */
|
||||
|
|
@ -3209,10 +3213,10 @@ write_one_file(Image *output, Image *image, int convert_to_8bit)
|
|||
else if (image->opts & USE_FILE)
|
||||
{
|
||||
#ifdef PNG_SIMPLIFIED_WRITE_STDIO_SUPPORTED
|
||||
static int counter = 0;
|
||||
static unsigned int counter = 0;
|
||||
char name[32];
|
||||
|
||||
sprintf(name, "%s%d.png", tmpf, ++counter);
|
||||
sprintf(name, "%s%u.png", tmpf, ++counter);
|
||||
|
||||
if (png_image_write_to_file(&image->image, name, convert_to_8bit,
|
||||
image->buffer+16, (png_int_32)image->stride, image->colormap))
|
||||
|
|
@ -3496,7 +3500,7 @@ main(int argc, char **argv)
|
|||
int retval = 0;
|
||||
int c;
|
||||
|
||||
#if PNG_LIBPNG_VER >= 10700
|
||||
#if PNG_LIBPNG_VER == 10700
|
||||
/* This error should not exist in 1.7 or later: */
|
||||
opts |= GBG_ERROR;
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
|
||||
/* pngunknown.c - test the read side unknown chunk handling
|
||||
*
|
||||
* Last changed in libpng 1.6.32 [August 24, 2017]
|
||||
* Copyright (c) 2021-2025 Cosmin Truta
|
||||
* Copyright (c) 2015,2017 Glenn Randers-Pehrson
|
||||
* Written by John Cunningham Bowler
|
||||
*
|
||||
|
|
@ -33,7 +32,7 @@
|
|||
/* 1.6.1 added support for the configure test harness, which uses 77 to indicate
|
||||
* a skipped test, in earlier versions we need to succeed on a skipped test, so:
|
||||
*/
|
||||
#if PNG_LIBPNG_VER >= 10601 && defined(HAVE_CONFIG_H)
|
||||
#if defined(HAVE_CONFIG_H)
|
||||
# define SKIP 77
|
||||
#else
|
||||
# define SKIP 0
|
||||
|
|
@ -55,48 +54,7 @@
|
|||
#if defined(PNG_READ_USER_CHUNKS_SUPPORTED) ||\
|
||||
defined(PNG_SAVE_UNKNOWN_CHUNKS_SUPPORTED)
|
||||
|
||||
#if PNG_LIBPNG_VER < 10500
|
||||
/* This deliberately lacks the const. */
|
||||
typedef png_byte *png_const_bytep;
|
||||
|
||||
/* This is copied from 1.5.1 png.h: */
|
||||
#define PNG_INTERLACE_ADAM7_PASSES 7
|
||||
#define PNG_PASS_START_ROW(pass) (((1U&~(pass))<<(3-((pass)>>1)))&7)
|
||||
#define PNG_PASS_START_COL(pass) (((1U& (pass))<<(3-(((pass)+1)>>1)))&7)
|
||||
#define PNG_PASS_ROW_SHIFT(pass) ((pass)>2?(8-(pass))>>1:3)
|
||||
#define PNG_PASS_COL_SHIFT(pass) ((pass)>1?(7-(pass))>>1:3)
|
||||
#define PNG_PASS_ROWS(height, pass) (((height)+(((1<<PNG_PASS_ROW_SHIFT(pass))\
|
||||
-1)-PNG_PASS_START_ROW(pass)))>>PNG_PASS_ROW_SHIFT(pass))
|
||||
#define PNG_PASS_COLS(width, pass) (((width)+(((1<<PNG_PASS_COL_SHIFT(pass))\
|
||||
-1)-PNG_PASS_START_COL(pass)))>>PNG_PASS_COL_SHIFT(pass))
|
||||
#define PNG_ROW_FROM_PASS_ROW(yIn, pass) \
|
||||
(((yIn)<<PNG_PASS_ROW_SHIFT(pass))+PNG_PASS_START_ROW(pass))
|
||||
#define PNG_COL_FROM_PASS_COL(xIn, pass) \
|
||||
(((xIn)<<PNG_PASS_COL_SHIFT(pass))+PNG_PASS_START_COL(pass))
|
||||
#define PNG_PASS_MASK(pass,off) ( \
|
||||
((0x110145AFU>>(((7-(off))-(pass))<<2)) & 0xFU) | \
|
||||
((0x01145AF0U>>(((7-(off))-(pass))<<2)) & 0xF0U))
|
||||
#define PNG_ROW_IN_INTERLACE_PASS(y, pass) \
|
||||
((PNG_PASS_MASK(pass,0) >> ((y)&7)) & 1)
|
||||
#define PNG_COL_IN_INTERLACE_PASS(x, pass) \
|
||||
((PNG_PASS_MASK(pass,1) >> ((x)&7)) & 1)
|
||||
|
||||
/* These are needed too for the default build: */
|
||||
#define PNG_WRITE_16BIT_SUPPORTED
|
||||
#define PNG_READ_16BIT_SUPPORTED
|
||||
|
||||
/* This comes from pnglibconf.h after 1.5: */
|
||||
#define PNG_FP_1 100000
|
||||
#define PNG_GAMMA_THRESHOLD_FIXED\
|
||||
((png_fixed_point)(PNG_GAMMA_THRESHOLD * PNG_FP_1))
|
||||
#endif
|
||||
|
||||
#if PNG_LIBPNG_VER < 10600
|
||||
/* 1.6.0 constifies many APIs. The following exists to allow pngvalid to be
|
||||
* compiled against earlier versions.
|
||||
*/
|
||||
# define png_const_structp png_structp
|
||||
#endif
|
||||
|
||||
#if PNG_LIBPNG_VER < 10700
|
||||
/* Copied from libpng 1.7.0 png.h */
|
||||
|
|
@ -114,6 +72,8 @@ typedef png_byte *png_const_bytep;
|
|||
#define png_PLTE PNG_U32( 80, 76, 84, 69)
|
||||
#define png_bKGD PNG_U32( 98, 75, 71, 68)
|
||||
#define png_cHRM PNG_U32( 99, 72, 82, 77)
|
||||
#define png_cICP PNG_U32( 99, 73, 67, 80) /* PNGv3 */
|
||||
#define png_cLLI PNG_U32( 99, 76, 76, 73) /* PNGv3 */
|
||||
#define png_eXIf PNG_U32(101, 88, 73, 102) /* registered July 2017 */
|
||||
#define png_fRAc PNG_U32(102, 82, 65, 99) /* registered, not defined */
|
||||
#define png_gAMA PNG_U32(103, 65, 77, 65)
|
||||
|
|
@ -123,6 +83,7 @@ typedef png_byte *png_const_bytep;
|
|||
#define png_hIST PNG_U32(104, 73, 83, 84)
|
||||
#define png_iCCP PNG_U32(105, 67, 67, 80)
|
||||
#define png_iTXt PNG_U32(105, 84, 88, 116)
|
||||
#define png_mDCV PNG_U32(109, 68, 67, 86) /* PNGv3 */
|
||||
#define png_oFFs PNG_U32(111, 70, 70, 115)
|
||||
#define png_pCAL PNG_U32(112, 67, 65, 76)
|
||||
#define png_pHYs PNG_U32(112, 72, 89, 115)
|
||||
|
|
@ -209,6 +170,20 @@ static struct
|
|||
0,
|
||||
# else
|
||||
1,
|
||||
# endif
|
||||
1, START, 0 },
|
||||
{ "cICP", PNG_INFO_cICP, png_cICP,
|
||||
# ifdef PNG_READ_cICP_SUPPORTED
|
||||
0,
|
||||
# else
|
||||
1,
|
||||
# endif
|
||||
1, START, 0 },
|
||||
{ "cLLI", PNG_INFO_cLLI, png_cLLI,
|
||||
# ifdef PNG_READ_cLLI_SUPPORTED
|
||||
0,
|
||||
# else
|
||||
1,
|
||||
# endif
|
||||
1, START, 0 },
|
||||
{ "eXIf", PNG_INFO_eXIf, png_eXIf,
|
||||
|
|
@ -246,6 +221,13 @@ static struct
|
|||
1,
|
||||
# endif
|
||||
1, ABSENT, 0 },
|
||||
{ "mDCV", PNG_INFO_mDCV, png_mDCV,
|
||||
# ifdef PNG_READ_mDCV_SUPPORTED
|
||||
0,
|
||||
# else
|
||||
1,
|
||||
# endif
|
||||
1, START, 0 },
|
||||
{ "oFFs", PNG_INFO_oFFs, png_oFFs,
|
||||
# ifdef PNG_READ_oFFs_SUPPORTED
|
||||
0,
|
||||
|
|
@ -370,7 +352,9 @@ find_by_flag(png_uint_32 flag)
|
|||
{
|
||||
int i = NINFO;
|
||||
|
||||
while (--i >= 0) if (chunk_info[i].flag == flag) return i;
|
||||
while (--i >= 0)
|
||||
if (chunk_info[i].flag == flag)
|
||||
return i;
|
||||
|
||||
fprintf(stderr, "pngunknown: internal error\n");
|
||||
exit(4);
|
||||
|
|
@ -547,27 +531,30 @@ read_callback(png_structp pp, png_unknown_chunkp pc)
|
|||
|
||||
case PNG_HANDLE_CHUNK_AS_DEFAULT:
|
||||
case PNG_HANDLE_CHUNK_NEVER:
|
||||
discard = 1/*handled; discard*/;
|
||||
discard = 1; /*handled; discard*/
|
||||
break;
|
||||
|
||||
case PNG_HANDLE_CHUNK_IF_SAFE:
|
||||
case PNG_HANDLE_CHUNK_ALWAYS:
|
||||
discard = 0/*not handled; keep*/;
|
||||
discard = 0; /*not handled; keep*/
|
||||
break;
|
||||
}
|
||||
|
||||
/* Also store information about this chunk in the display, the relevant flag
|
||||
* is set if the chunk is to be kept ('not handled'.)
|
||||
*/
|
||||
if (chunk >= 0) if (!discard) /* stupidity to stop a GCC warning */
|
||||
if (chunk >= 0)
|
||||
{
|
||||
png_uint_32 flag = chunk_info[chunk].flag;
|
||||
if (!discard) /* stupidity to stop a GCC warning */
|
||||
{
|
||||
png_uint_32 flag = chunk_info[chunk].flag;
|
||||
|
||||
if (pc->location & PNG_AFTER_IDAT)
|
||||
d->after_IDAT |= flag;
|
||||
if (pc->location & PNG_AFTER_IDAT)
|
||||
d->after_IDAT |= flag;
|
||||
|
||||
else
|
||||
d->before_IDAT |= flag;
|
||||
else
|
||||
d->before_IDAT |= flag;
|
||||
}
|
||||
}
|
||||
|
||||
/* However if there is no support to store unknown chunks don't ask libpng to
|
||||
|
|
@ -841,8 +828,9 @@ check(FILE *fp, int argc, const char **argv, png_uint_32p flags/*out*/,
|
|||
{
|
||||
png_uint_32 y;
|
||||
|
||||
for (y=0; y<height; ++y) if (PNG_ROW_IN_INTERLACE_PASS(y, ipass))
|
||||
png_read_row(d->png_ptr, NULL, NULL);
|
||||
for (y=0; y<height; ++y)
|
||||
if (PNG_ROW_IN_INTERLACE_PASS(y, ipass))
|
||||
png_read_row(d->png_ptr, NULL, NULL);
|
||||
}
|
||||
}
|
||||
} /* interlaced */
|
||||
|
|
@ -1091,15 +1079,15 @@ perform_one_test_safe(FILE *fp, int argc, const char **argv,
|
|||
|
||||
static const char *standard_tests[] =
|
||||
{
|
||||
"discard", "default=discard", 0,
|
||||
"save", "default=save", 0,
|
||||
"if-safe", "default=if-safe", 0,
|
||||
"vpAg", "vpAg=if-safe", 0,
|
||||
"sTER", "sTER=if-safe", 0,
|
||||
"IDAT", "default=discard", "IDAT=save", 0,
|
||||
"sAPI", "bKGD=save", "cHRM=save", "gAMA=save", "all=discard", "iCCP=save",
|
||||
"sBIT=save", "sRGB=save", "eXIf=save", 0,
|
||||
0/*end*/
|
||||
"discard", "default=discard", NULL,
|
||||
"save", "default=save", NULL,
|
||||
"if-safe", "default=if-safe", NULL,
|
||||
"vpAg", "vpAg=if-safe", NULL,
|
||||
"sTER", "sTER=if-safe", NULL,
|
||||
"IDAT", "default=discard", "IDAT=save", NULL,
|
||||
"sAPI", "bKGD=save", "cHRM=save", "gAMA=save", "all=discard", "iCCP=save",
|
||||
"sBIT=save", "sRGB=save", "eXIf=save", NULL,
|
||||
NULL /*end*/
|
||||
};
|
||||
|
||||
static PNG_NORETURN void
|
||||
|
|
@ -1115,7 +1103,7 @@ int
|
|||
main(int argc, const char **argv)
|
||||
{
|
||||
FILE *fp;
|
||||
png_uint_32 default_flags[4/*valid,unknown{before,after}*/];
|
||||
png_uint_32 default_flags[4]; /*valid,unknown{before,after}*/
|
||||
int strict = 0, default_tests = 0;
|
||||
const char *count_argv = "default=save";
|
||||
const char *touch_file = NULL;
|
||||
|
|
@ -1153,8 +1141,9 @@ main(int argc, const char **argv)
|
|||
/* GCC BUG: if (default_tests && argc != 1) triggers some weird GCC argc
|
||||
* optimization which causes warnings with -Wstrict-overflow!
|
||||
*/
|
||||
else if (default_tests) if (argc != 1)
|
||||
usage(d.program, "extra arguments");
|
||||
else if (default_tests)
|
||||
if (argc != 1)
|
||||
usage(d.program, "extra arguments");
|
||||
|
||||
/* The name of the test file is the last argument; remove it. */
|
||||
d.file = argv[--argc];
|
||||
|
|
@ -1216,7 +1205,11 @@ main(int argc, const char **argv)
|
|||
const char *result;
|
||||
int arg_count = 0;
|
||||
|
||||
while (*next) ++next, ++arg_count;
|
||||
while (*next != NULL)
|
||||
{
|
||||
++next;
|
||||
++arg_count;
|
||||
}
|
||||
|
||||
perform_one_test_safe(fp, arg_count, test, default_flags, &d,
|
||||
this_test);
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
|
||||
/* pngvalid.c - validate libpng by constructing then reading png files.
|
||||
*
|
||||
* Last changed in libpng 1.6.31 [July 27, 2017]
|
||||
* Copyright (c) 2021-2025 Cosmin Truta
|
||||
* Copyright (c) 2014-2017 John Cunningham Bowler
|
||||
*
|
||||
* This code is released under the libpng license.
|
||||
|
|
@ -22,6 +21,7 @@
|
|||
#define _ISOC99_SOURCE 1 /* For floating point */
|
||||
#define _GNU_SOURCE 1 /* For the floating point exception extension */
|
||||
#define _BSD_SOURCE 1 /* For the floating point exception extension */
|
||||
#define _DEFAULT_SOURCE 1 /* For the floating point exception extension */
|
||||
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
|
|
@ -62,59 +62,21 @@
|
|||
/* 1.6.1 added support for the configure test harness, which uses 77 to indicate
|
||||
* a skipped test, in earlier versions we need to succeed on a skipped test, so:
|
||||
*/
|
||||
#if PNG_LIBPNG_VER >= 10601 && defined(HAVE_CONFIG_H)
|
||||
#if defined(HAVE_CONFIG_H)
|
||||
# define SKIP 77
|
||||
#else
|
||||
# define SKIP 0
|
||||
#endif
|
||||
|
||||
/* pngvalid requires write support and one of the fixed or floating point APIs.
|
||||
* progressive read is also required currently as the progressive read pointer
|
||||
* is used to record the 'display' structure.
|
||||
*/
|
||||
#if defined(PNG_WRITE_SUPPORTED) &&\
|
||||
(defined(PNG_FIXED_POINT_SUPPORTED) || defined(PNG_FLOATING_POINT_SUPPORTED))
|
||||
#if defined PNG_WRITE_SUPPORTED &&\
|
||||
(defined PNG_PROGRESSIVE_READ_SUPPORTED) &&\
|
||||
(defined PNG_FIXED_POINT_SUPPORTED || defined PNG_FLOATING_POINT_SUPPORTED)
|
||||
|
||||
#if PNG_LIBPNG_VER < 10500
|
||||
/* This deliberately lacks the const. */
|
||||
typedef png_byte *png_const_bytep;
|
||||
|
||||
/* This is copied from 1.5.1 png.h: */
|
||||
#define PNG_INTERLACE_ADAM7_PASSES 7
|
||||
#define PNG_PASS_START_ROW(pass) (((1U&~(pass))<<(3-((pass)>>1)))&7)
|
||||
#define PNG_PASS_START_COL(pass) (((1U& (pass))<<(3-(((pass)+1)>>1)))&7)
|
||||
#define PNG_PASS_ROW_SHIFT(pass) ((pass)>2?(8-(pass))>>1:3)
|
||||
#define PNG_PASS_COL_SHIFT(pass) ((pass)>1?(7-(pass))>>1:3)
|
||||
#define PNG_PASS_ROWS(height, pass) (((height)+(((1<<PNG_PASS_ROW_SHIFT(pass))\
|
||||
-1)-PNG_PASS_START_ROW(pass)))>>PNG_PASS_ROW_SHIFT(pass))
|
||||
#define PNG_PASS_COLS(width, pass) (((width)+(((1<<PNG_PASS_COL_SHIFT(pass))\
|
||||
-1)-PNG_PASS_START_COL(pass)))>>PNG_PASS_COL_SHIFT(pass))
|
||||
#define PNG_ROW_FROM_PASS_ROW(yIn, pass) \
|
||||
(((yIn)<<PNG_PASS_ROW_SHIFT(pass))+PNG_PASS_START_ROW(pass))
|
||||
#define PNG_COL_FROM_PASS_COL(xIn, pass) \
|
||||
(((xIn)<<PNG_PASS_COL_SHIFT(pass))+PNG_PASS_START_COL(pass))
|
||||
#define PNG_PASS_MASK(pass,off) ( \
|
||||
((0x110145AFU>>(((7-(off))-(pass))<<2)) & 0xFU) | \
|
||||
((0x01145AF0U>>(((7-(off))-(pass))<<2)) & 0xF0U))
|
||||
#define PNG_ROW_IN_INTERLACE_PASS(y, pass) \
|
||||
((PNG_PASS_MASK(pass,0) >> ((y)&7)) & 1)
|
||||
#define PNG_COL_IN_INTERLACE_PASS(x, pass) \
|
||||
((PNG_PASS_MASK(pass,1) >> ((x)&7)) & 1)
|
||||
|
||||
/* These are needed too for the default build: */
|
||||
#define PNG_WRITE_16BIT_SUPPORTED
|
||||
#define PNG_READ_16BIT_SUPPORTED
|
||||
|
||||
/* This comes from pnglibconf.h after 1.5: */
|
||||
#define PNG_FP_1 100000
|
||||
#define PNG_GAMMA_THRESHOLD_FIXED\
|
||||
((png_fixed_point)(PNG_GAMMA_THRESHOLD * PNG_FP_1))
|
||||
#endif
|
||||
|
||||
#if PNG_LIBPNG_VER < 10600
|
||||
/* 1.6.0 constifies many APIs, the following exists to allow pngvalid to be
|
||||
* compiled against earlier versions.
|
||||
*/
|
||||
# define png_const_structp png_structp
|
||||
#endif
|
||||
|
||||
#ifndef RELEASE_BUILD
|
||||
/* RELEASE_BUILD is true for releases and release candidates: */
|
||||
|
|
@ -300,20 +262,20 @@ make_four_random_bytes(png_uint_32* seed, png_bytep bytes)
|
|||
#if defined PNG_READ_SUPPORTED || defined PNG_WRITE_tRNS_SUPPORTED ||\
|
||||
defined PNG_WRITE_FILTER_SUPPORTED
|
||||
static void
|
||||
randomize(void *pv, size_t size)
|
||||
randomize_bytes(void *pv, size_t size)
|
||||
{
|
||||
static png_uint_32 random_seed[2] = {0x56789abc, 0xd};
|
||||
make_random_bytes(random_seed, pv, size);
|
||||
}
|
||||
|
||||
#define R8(this) randomize(&(this), sizeof (this))
|
||||
#define R8(this) randomize_bytes(&(this), sizeof (this))
|
||||
|
||||
#ifdef PNG_READ_SUPPORTED
|
||||
static png_byte
|
||||
random_byte(void)
|
||||
{
|
||||
unsigned char b1[1];
|
||||
randomize(b1, sizeof b1);
|
||||
randomize_bytes(b1, sizeof b1);
|
||||
return b1[0];
|
||||
}
|
||||
#endif /* READ */
|
||||
|
|
@ -322,7 +284,7 @@ static png_uint_16
|
|||
random_u16(void)
|
||||
{
|
||||
unsigned char b2[2];
|
||||
randomize(b2, sizeof b2);
|
||||
randomize_bytes(b2, sizeof b2);
|
||||
return png_get_uint_16(b2);
|
||||
}
|
||||
|
||||
|
|
@ -332,7 +294,7 @@ static png_uint_32
|
|||
random_u32(void)
|
||||
{
|
||||
unsigned char b4[4];
|
||||
randomize(b4, sizeof b4);
|
||||
randomize_bytes(b4, sizeof b4);
|
||||
return png_get_uint_32(b4);
|
||||
}
|
||||
#endif /* READ_FILLER || READ_RGB_TO_GRAY */
|
||||
|
|
@ -644,34 +606,8 @@ row_copy(png_bytep toBuffer, png_const_bytep fromBuffer, unsigned int bitWidth,
|
|||
static int
|
||||
pixel_cmp(png_const_bytep pa, png_const_bytep pb, png_uint_32 bit_width)
|
||||
{
|
||||
#if PNG_LIBPNG_VER < 10506
|
||||
if (memcmp(pa, pb, bit_width>>3) == 0)
|
||||
{
|
||||
png_uint_32 p;
|
||||
|
||||
if ((bit_width & 7) == 0) return 0;
|
||||
|
||||
/* Ok, any differences? */
|
||||
p = pa[bit_width >> 3];
|
||||
p ^= pb[bit_width >> 3];
|
||||
|
||||
if (p == 0) return 0;
|
||||
|
||||
/* There are, but they may not be significant, remove the bits
|
||||
* after the end (the low order bits in PNG.)
|
||||
*/
|
||||
bit_width &= 7;
|
||||
p >>= 8-bit_width;
|
||||
|
||||
if (p == 0) return 0;
|
||||
}
|
||||
#else
|
||||
/* From libpng-1.5.6 the overwrite should be fixed, so compare the trailing
|
||||
* bits too:
|
||||
*/
|
||||
if (memcmp(pa, pb, (bit_width+7)>>3) == 0)
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
/* Return the index of the changed byte. */
|
||||
{
|
||||
|
|
@ -2570,7 +2506,7 @@ modifier_init(png_modifier *pm)
|
|||
* in the rgb_to_gray check, replacing it with an exact copy of the libpng 1.5
|
||||
* algorithm.
|
||||
*/
|
||||
#define DIGITIZE PNG_LIBPNG_VER < 10700
|
||||
#define DIGITIZE PNG_LIBPNG_VER != 10700
|
||||
|
||||
/* If pm->calculations_use_input_precision is set then operations will happen
|
||||
* with the precision of the input, not the precision of the output depth.
|
||||
|
|
@ -3982,7 +3918,7 @@ transform_row(png_const_structp pp, png_byte buffer[TRANSFORM_ROWMAX],
|
|||
# define check_interlace_type(type) ((void)(type))
|
||||
# define set_write_interlace_handling(pp,type) png_set_interlace_handling(pp)
|
||||
# define do_own_interlace 0
|
||||
#elif PNG_LIBPNG_VER < 10700
|
||||
#elif PNG_LIBPNG_VER != 10700
|
||||
# define set_write_interlace_handling(pp,type) (1)
|
||||
static void
|
||||
check_interlace_type(int const interlace_type)
|
||||
|
|
@ -4010,7 +3946,7 @@ check_interlace_type(int const interlace_type)
|
|||
# define do_own_interlace 1
|
||||
#endif /* WRITE_INTERLACING tests */
|
||||
|
||||
#if PNG_LIBPNG_VER >= 10700 || defined PNG_WRITE_INTERLACING_SUPPORTED
|
||||
#if PNG_LIBPNG_VER == 10700 || defined PNG_WRITE_INTERLACING_SUPPORTED
|
||||
# define CAN_WRITE_INTERLACE 1
|
||||
#else
|
||||
# define CAN_WRITE_INTERLACE 0
|
||||
|
|
@ -4629,10 +4565,10 @@ static const struct
|
|||
{
|
||||
/* no warnings makes these errors undetectable prior to 1.7.0 */
|
||||
{ sBIT0_error_fn, "sBIT(0): failed to detect error",
|
||||
PNG_LIBPNG_VER < 10700 },
|
||||
PNG_LIBPNG_VER != 10700 },
|
||||
|
||||
{ sBIT_error_fn, "sBIT(too big): failed to detect error",
|
||||
PNG_LIBPNG_VER < 10700 },
|
||||
PNG_LIBPNG_VER != 10700 },
|
||||
};
|
||||
|
||||
static void
|
||||
|
|
@ -4848,9 +4784,7 @@ perform_formatting_test(png_store *ps)
|
|||
{
|
||||
png_const_charp correct = "29 Aug 2079 13:53:60 +0000";
|
||||
png_const_charp result;
|
||||
# if PNG_LIBPNG_VER >= 10600
|
||||
char timestring[29];
|
||||
# endif
|
||||
char timestring[29];
|
||||
png_structp pp;
|
||||
png_time pt;
|
||||
|
||||
|
|
@ -5822,8 +5756,9 @@ test_standard(png_modifier* const pm, png_byte const colour_type,
|
|||
for (interlace_type = PNG_INTERLACE_NONE;
|
||||
interlace_type < INTERLACE_LAST; ++interlace_type)
|
||||
{
|
||||
standard_test(&pm->this, FILEID(colour_type, DEPTH(bdlo), 0/*palette*/,
|
||||
interlace_type, 0, 0, 0), do_read_interlace, pm->use_update_info);
|
||||
standard_test(&pm->this, FILEID(colour_type, DEPTH(bdlo),
|
||||
0/*palette*/, interlace_type, 0, 0, 0), do_read_interlace,
|
||||
pm->use_update_info);
|
||||
|
||||
if (fail(pm))
|
||||
return 0;
|
||||
|
|
@ -5876,47 +5811,50 @@ test_size(png_modifier* const pm, png_byte const colour_type,
|
|||
{
|
||||
png_uint_32 h, w;
|
||||
|
||||
for (h=1; h<=16; h+=hinc[bdlo]) for (w=1; w<=16; w+=winc[bdlo])
|
||||
for (h=1; h<=16; h+=hinc[bdlo])
|
||||
{
|
||||
/* First test all the 'size' images against the sequential
|
||||
* reader using libpng to deinterlace (where required.) This
|
||||
* validates the write side of libpng. There are four possibilities
|
||||
* to validate.
|
||||
*/
|
||||
standard_test(&pm->this, FILEID(colour_type, DEPTH(bdlo), 0/*palette*/,
|
||||
PNG_INTERLACE_NONE, w, h, 0), 0/*do_interlace*/,
|
||||
pm->use_update_info);
|
||||
for (w=1; w<=16; w+=winc[bdlo])
|
||||
{
|
||||
/* First test all the 'size' images against the sequential
|
||||
* reader using libpng to deinterlace (where required.) This
|
||||
* validates the write side of libpng. There are four possibilities
|
||||
* to validate.
|
||||
*/
|
||||
standard_test(&pm->this, FILEID(colour_type, DEPTH(bdlo),
|
||||
0/*palette*/, PNG_INTERLACE_NONE, w, h, 0), 0/*do_interlace*/,
|
||||
pm->use_update_info);
|
||||
|
||||
if (fail(pm))
|
||||
return 0;
|
||||
if (fail(pm))
|
||||
return 0;
|
||||
|
||||
standard_test(&pm->this, FILEID(colour_type, DEPTH(bdlo), 0/*palette*/,
|
||||
PNG_INTERLACE_NONE, w, h, 1), 0/*do_interlace*/,
|
||||
pm->use_update_info);
|
||||
standard_test(&pm->this, FILEID(colour_type, DEPTH(bdlo),
|
||||
0/*palette*/, PNG_INTERLACE_NONE, w, h, 1), 0/*do_interlace*/,
|
||||
pm->use_update_info);
|
||||
|
||||
if (fail(pm))
|
||||
return 0;
|
||||
if (fail(pm))
|
||||
return 0;
|
||||
|
||||
/* Now validate the interlaced read side - do_interlace true,
|
||||
* in the progressive case this does actually make a difference
|
||||
* to the code used in the non-interlaced case too.
|
||||
*/
|
||||
standard_test(&pm->this, FILEID(colour_type, DEPTH(bdlo), 0/*palette*/,
|
||||
PNG_INTERLACE_NONE, w, h, 0), 1/*do_interlace*/,
|
||||
pm->use_update_info);
|
||||
/* Now validate the interlaced read side - do_interlace true,
|
||||
* in the progressive case this does actually make a difference
|
||||
* to the code used in the non-interlaced case too.
|
||||
*/
|
||||
standard_test(&pm->this, FILEID(colour_type, DEPTH(bdlo),
|
||||
0/*palette*/, PNG_INTERLACE_NONE, w, h, 0), 1/*do_interlace*/,
|
||||
pm->use_update_info);
|
||||
|
||||
if (fail(pm))
|
||||
return 0;
|
||||
if (fail(pm))
|
||||
return 0;
|
||||
|
||||
# if CAN_WRITE_INTERLACE
|
||||
/* Validate the pngvalid code itself: */
|
||||
standard_test(&pm->this, FILEID(colour_type, DEPTH(bdlo), 0/*palette*/,
|
||||
PNG_INTERLACE_ADAM7, w, h, 1), 1/*do_interlace*/,
|
||||
pm->use_update_info);
|
||||
# if CAN_WRITE_INTERLACE
|
||||
/* Validate the pngvalid code itself: */
|
||||
standard_test(&pm->this, FILEID(colour_type, DEPTH(bdlo),
|
||||
0/*palette*/, PNG_INTERLACE_ADAM7, w, h, 1), 1/*do_interlace*/,
|
||||
pm->use_update_info);
|
||||
|
||||
if (fail(pm))
|
||||
return 0;
|
||||
# endif
|
||||
if (fail(pm))
|
||||
return 0;
|
||||
# endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -5927,45 +5865,48 @@ test_size(png_modifier* const pm, png_byte const colour_type,
|
|||
{
|
||||
png_uint_32 h, w;
|
||||
|
||||
for (h=1; h<=16; h+=hinc[bdlo]) for (w=1; w<=16; w+=winc[bdlo])
|
||||
for (h=1; h<=16; h+=hinc[bdlo])
|
||||
{
|
||||
# ifdef PNG_READ_INTERLACING_SUPPORTED
|
||||
/* Test with pngvalid generated interlaced images first; we have
|
||||
* already verify these are ok (unless pngvalid has self-consistent
|
||||
* read/write errors, which is unlikely), so this detects errors in the
|
||||
* read side first:
|
||||
*/
|
||||
# if CAN_WRITE_INTERLACE
|
||||
standard_test(&pm->this, FILEID(colour_type, DEPTH(bdlo), 0/*palette*/,
|
||||
PNG_INTERLACE_ADAM7, w, h, 1), 0/*do_interlace*/,
|
||||
pm->use_update_info);
|
||||
for (w=1; w<=16; w+=winc[bdlo])
|
||||
{
|
||||
# ifdef PNG_READ_INTERLACING_SUPPORTED
|
||||
/* Test with pngvalid generated interlaced images first; we have
|
||||
* already verify these are ok (unless pngvalid has self-consistent
|
||||
* read/write errors, which is unlikely), so this detects errors in
|
||||
* the read side first:
|
||||
*/
|
||||
# if CAN_WRITE_INTERLACE
|
||||
standard_test(&pm->this, FILEID(colour_type, DEPTH(bdlo),
|
||||
0/*palette*/, PNG_INTERLACE_ADAM7, w, h, 1), 0/*do_interlace*/,
|
||||
pm->use_update_info);
|
||||
|
||||
if (fail(pm))
|
||||
return 0;
|
||||
# endif
|
||||
# endif /* READ_INTERLACING */
|
||||
if (fail(pm))
|
||||
return 0;
|
||||
# endif
|
||||
# endif /* READ_INTERLACING */
|
||||
|
||||
# ifdef PNG_WRITE_INTERLACING_SUPPORTED
|
||||
/* Test the libpng write side against the pngvalid read side: */
|
||||
standard_test(&pm->this, FILEID(colour_type, DEPTH(bdlo), 0/*palette*/,
|
||||
PNG_INTERLACE_ADAM7, w, h, 0), 1/*do_interlace*/,
|
||||
pm->use_update_info);
|
||||
# ifdef PNG_WRITE_INTERLACING_SUPPORTED
|
||||
/* Test the libpng write side against the pngvalid read side: */
|
||||
standard_test(&pm->this, FILEID(colour_type, DEPTH(bdlo),
|
||||
0/*palette*/, PNG_INTERLACE_ADAM7, w, h, 0), 1/*do_interlace*/,
|
||||
pm->use_update_info);
|
||||
|
||||
if (fail(pm))
|
||||
return 0;
|
||||
# endif
|
||||
if (fail(pm))
|
||||
return 0;
|
||||
# endif
|
||||
|
||||
# ifdef PNG_READ_INTERLACING_SUPPORTED
|
||||
# ifdef PNG_WRITE_INTERLACING_SUPPORTED
|
||||
/* Test both together: */
|
||||
standard_test(&pm->this, FILEID(colour_type, DEPTH(bdlo), 0/*palette*/,
|
||||
PNG_INTERLACE_ADAM7, w, h, 0), 0/*do_interlace*/,
|
||||
pm->use_update_info);
|
||||
# ifdef PNG_READ_INTERLACING_SUPPORTED
|
||||
# ifdef PNG_WRITE_INTERLACING_SUPPORTED
|
||||
/* Test both together: */
|
||||
standard_test(&pm->this, FILEID(colour_type, DEPTH(bdlo),
|
||||
0/*palette*/, PNG_INTERLACE_ADAM7, w, h, 0), 0/*do_interlace*/,
|
||||
pm->use_update_info);
|
||||
|
||||
if (fail(pm))
|
||||
return 0;
|
||||
# endif
|
||||
# endif /* READ_INTERLACING */
|
||||
if (fail(pm))
|
||||
return 0;
|
||||
# endif
|
||||
# endif /* READ_INTERLACING */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -6225,7 +6166,7 @@ image_pixel_add_alpha(image_pixel *this, const standard_display *display,
|
|||
{
|
||||
if (this->colour_type == PNG_COLOR_TYPE_GRAY)
|
||||
{
|
||||
# if PNG_LIBPNG_VER < 10700
|
||||
# if PNG_LIBPNG_VER != 10700
|
||||
if (!for_background && this->bit_depth < 8)
|
||||
this->bit_depth = this->sample_depth = 8;
|
||||
# endif
|
||||
|
|
@ -6235,7 +6176,7 @@ image_pixel_add_alpha(image_pixel *this, const standard_display *display,
|
|||
/* After 1.7 the expansion of bit depth only happens if there is a
|
||||
* tRNS chunk to expand at this point.
|
||||
*/
|
||||
# if PNG_LIBPNG_VER >= 10700
|
||||
# if PNG_LIBPNG_VER == 10700
|
||||
if (!for_background && this->bit_depth < 8)
|
||||
this->bit_depth = this->sample_depth = 8;
|
||||
# endif
|
||||
|
|
@ -6711,7 +6652,7 @@ transform_range_check(png_const_structp pp, unsigned int r, unsigned int g,
|
|||
unsigned int out, png_byte sample_depth, double err, double limit,
|
||||
const char *name, double digitization_error)
|
||||
{
|
||||
/* Compare the scaled, digitzed, values of our local calculation (in+-err)
|
||||
/* Compare the scaled, digitized, values of our local calculation (in+-err)
|
||||
* with the digitized values libpng produced; 'sample_depth' is the actual
|
||||
* digitization depth of the libpng output colors (the bit depth except for
|
||||
* palette images where it is always 8.) The check on 'err' is to detect
|
||||
|
|
@ -7116,7 +7057,7 @@ image_transform_png_set_tRNS_to_alpha_mod(const image_transform *this,
|
|||
image_pixel *that, png_const_structp pp,
|
||||
const transform_display *display)
|
||||
{
|
||||
#if PNG_LIBPNG_VER < 10700
|
||||
#if PNG_LIBPNG_VER != 10700
|
||||
/* LIBPNG BUG: this always forces palette images to RGB. */
|
||||
if (that->colour_type == PNG_COLOR_TYPE_PALETTE)
|
||||
image_pixel_convert_PLTE(that);
|
||||
|
|
@ -7126,13 +7067,13 @@ image_transform_png_set_tRNS_to_alpha_mod(const image_transform *this,
|
|||
* convert to an alpha channel.
|
||||
*/
|
||||
if (that->have_tRNS)
|
||||
# if PNG_LIBPNG_VER >= 10700
|
||||
# if PNG_LIBPNG_VER == 10700
|
||||
if (that->colour_type != PNG_COLOR_TYPE_PALETTE &&
|
||||
(that->colour_type & PNG_COLOR_MASK_ALPHA) == 0)
|
||||
# endif
|
||||
image_pixel_add_alpha(that, &display->this, 0/*!for background*/);
|
||||
|
||||
#if PNG_LIBPNG_VER < 10700
|
||||
#if PNG_LIBPNG_VER != 10700
|
||||
/* LIBPNG BUG: otherwise libpng still expands to 8 bits! */
|
||||
else
|
||||
{
|
||||
|
|
@ -7161,7 +7102,7 @@ image_transform_png_set_tRNS_to_alpha_add(image_transform *this,
|
|||
* any action on a palette image.
|
||||
*/
|
||||
return
|
||||
# if PNG_LIBPNG_VER >= 10700
|
||||
# if PNG_LIBPNG_VER == 10700
|
||||
colour_type != PNG_COLOR_TYPE_PALETTE &&
|
||||
# endif
|
||||
(colour_type & PNG_COLOR_MASK_ALPHA) == 0;
|
||||
|
|
@ -7302,7 +7243,7 @@ image_transform_png_set_expand_gray_1_2_4_to_8_mod(
|
|||
const image_transform *this, image_pixel *that, png_const_structp pp,
|
||||
const transform_display *display)
|
||||
{
|
||||
#if PNG_LIBPNG_VER < 10700
|
||||
#if PNG_LIBPNG_VER != 10700
|
||||
image_transform_png_set_expand_mod(this, that, pp, display);
|
||||
#else
|
||||
/* Only expand grayscale of bit depth less than 8: */
|
||||
|
|
@ -7318,7 +7259,7 @@ static int
|
|||
image_transform_png_set_expand_gray_1_2_4_to_8_add(image_transform *this,
|
||||
const image_transform **that, png_byte colour_type, png_byte bit_depth)
|
||||
{
|
||||
#if PNG_LIBPNG_VER < 10700
|
||||
#if PNG_LIBPNG_VER != 10700
|
||||
return image_transform_png_set_expand_add(this, that, colour_type,
|
||||
bit_depth);
|
||||
#else
|
||||
|
|
@ -7348,7 +7289,7 @@ image_transform_png_set_expand_16_set(const image_transform *this,
|
|||
png_set_expand_16(pp);
|
||||
|
||||
/* NOTE: prior to 1.7 libpng does SET_EXPAND as well, so tRNS is expanded. */
|
||||
# if PNG_LIBPNG_VER < 10700
|
||||
# if PNG_LIBPNG_VER != 10700
|
||||
if (that->this.has_tRNS)
|
||||
that->this.is_transparent = 1;
|
||||
# endif
|
||||
|
|
@ -7401,7 +7342,7 @@ image_transform_png_set_scale_16_set(const image_transform *this,
|
|||
transform_display *that, png_structp pp, png_infop pi)
|
||||
{
|
||||
png_set_scale_16(pp);
|
||||
# if PNG_LIBPNG_VER < 10700
|
||||
# if PNG_LIBPNG_VER != 10700
|
||||
/* libpng will limit the gamma table size: */
|
||||
that->max_gamma_8 = PNG_MAX_GAMMA_8;
|
||||
# endif
|
||||
|
|
@ -7449,7 +7390,7 @@ image_transform_png_set_strip_16_set(const image_transform *this,
|
|||
transform_display *that, png_structp pp, png_infop pi)
|
||||
{
|
||||
png_set_strip_16(pp);
|
||||
# if PNG_LIBPNG_VER < 10700
|
||||
# if PNG_LIBPNG_VER != 10700
|
||||
/* libpng will limit the gamma table size: */
|
||||
that->max_gamma_8 = PNG_MAX_GAMMA_8;
|
||||
# endif
|
||||
|
|
@ -7474,22 +7415,7 @@ image_transform_png_set_strip_16_mod(const image_transform *this,
|
|||
* 'scale' API (above) must be used.
|
||||
*/
|
||||
# ifdef PNG_READ_ACCURATE_SCALE_SUPPORTED
|
||||
# if PNG_LIBPNG_VER >= 10504
|
||||
# error PNG_READ_ACCURATE_SCALE should not be set
|
||||
# endif
|
||||
|
||||
/* The strip 16 algorithm drops the low 8 bits rather than calculating
|
||||
* 1/257, so we need to adjust the permitted errors appropriately:
|
||||
* Notice that this is only relevant prior to the addition of the
|
||||
* png_set_scale_16 API in 1.5.4 (but 1.5.4+ always defines the above!)
|
||||
*/
|
||||
{
|
||||
const double d = (255-128.5)/65535;
|
||||
that->rede += d;
|
||||
that->greene += d;
|
||||
that->bluee += d;
|
||||
that->alphae += d;
|
||||
}
|
||||
# error PNG_READ_ACCURATE_SCALE should not be set
|
||||
# endif
|
||||
}
|
||||
|
||||
|
|
@ -7635,8 +7561,8 @@ image_transform_png_set_rgb_to_gray_ini(const image_transform *this,
|
|||
|
||||
else
|
||||
{
|
||||
/* The default (built in) coeffcients, as above: */
|
||||
# if PNG_LIBPNG_VER < 10700
|
||||
/* The default (built in) coefficients, as above: */
|
||||
# if PNG_LIBPNG_VER != 10700
|
||||
data.red_coefficient = 6968 / 32768.;
|
||||
data.green_coefficient = 23434 / 32768.;
|
||||
data.blue_coefficient = 2366 / 32768.;
|
||||
|
|
@ -7719,7 +7645,7 @@ image_transform_png_set_rgb_to_gray_ini(const image_transform *this,
|
|||
* conversion adds another +/-2 in the 16-bit case and
|
||||
* +/-(1<<(15-PNG_MAX_GAMMA_8)) in the 8-bit case.
|
||||
*/
|
||||
# if PNG_LIBPNG_VER < 10700
|
||||
# if PNG_LIBPNG_VER != 10700
|
||||
if (that->this.bit_depth < 16)
|
||||
that->max_gamma_8 = PNG_MAX_GAMMA_8;
|
||||
# endif
|
||||
|
|
@ -7896,7 +7822,7 @@ image_transform_png_set_rgb_to_gray_mod(const image_transform *this,
|
|||
{
|
||||
double gray, err;
|
||||
|
||||
# if PNG_LIBPNG_VER < 10700
|
||||
# if PNG_LIBPNG_VER != 10700
|
||||
if (that->colour_type == PNG_COLOR_TYPE_PALETTE)
|
||||
image_pixel_convert_PLTE(that);
|
||||
# endif
|
||||
|
|
@ -8083,7 +8009,7 @@ image_transform_png_set_rgb_to_gray_mod(const image_transform *this,
|
|||
double b = that->bluef;
|
||||
double be = that->bluee;
|
||||
|
||||
# if PNG_LIBPNG_VER < 10700
|
||||
# if PNG_LIBPNG_VER != 10700
|
||||
/* The true gray case involves no math in earlier versions (not
|
||||
* true, there was some if gamma correction was happening too.)
|
||||
*/
|
||||
|
|
@ -9057,7 +8983,7 @@ image_transform_reset_count(void)
|
|||
static int
|
||||
image_transform_test_counter(png_uint_32 counter, unsigned int max)
|
||||
{
|
||||
/* Test the list to see if there is any point contining, given a current
|
||||
/* Test the list to see if there is any point continuing, given a current
|
||||
* counter and a 'max' value.
|
||||
*/
|
||||
image_transform *next = image_transform_first;
|
||||
|
|
@ -9862,7 +9788,7 @@ gamma_component_validate(const char *name, const validate_info *vi,
|
|||
* lost. This can result in up to a +/-1 error in the presence of
|
||||
* an sbit less than the bit depth.
|
||||
*/
|
||||
# if PNG_LIBPNG_VER < 10700
|
||||
# if PNG_LIBPNG_VER != 10700
|
||||
# define SBIT_ERROR .5
|
||||
# else
|
||||
# define SBIT_ERROR 1.
|
||||
|
|
@ -9922,47 +9848,6 @@ gamma_component_validate(const char *name, const validate_info *vi,
|
|||
* (chop) method of scaling was used.
|
||||
*/
|
||||
# ifndef PNG_READ_16_TO_8_ACCURATE_SCALE_SUPPORTED
|
||||
# if PNG_LIBPNG_VER < 10504
|
||||
/* This may be required for other components in the future,
|
||||
* but at present the presence of gamma correction effectively
|
||||
* prevents the errors in the component scaling (I don't quite
|
||||
* understand why, but since it's better this way I care not
|
||||
* to ask, JB 20110419.)
|
||||
*/
|
||||
if (pass == 0 && alpha < 0 && vi->scale16 && vi->sbit > 8 &&
|
||||
vi->sbit + vi->isbit_shift == 16)
|
||||
{
|
||||
tmp = ((id >> 8) - .5)/255;
|
||||
|
||||
if (tmp > 0)
|
||||
{
|
||||
is_lo = ceil(outmax * tmp - vi->maxout_total);
|
||||
if (is_lo < 0) is_lo = 0;
|
||||
}
|
||||
|
||||
else
|
||||
is_lo = 0;
|
||||
|
||||
tmp = ((id >> 8) + .5)/255;
|
||||
|
||||
if (tmp < 1)
|
||||
{
|
||||
is_hi = floor(outmax * tmp + vi->maxout_total);
|
||||
if (is_hi > outmax) is_hi = outmax;
|
||||
}
|
||||
|
||||
else
|
||||
is_hi = outmax;
|
||||
|
||||
if (!(od < is_lo || od > is_hi))
|
||||
{
|
||||
if (encoded_error < vi->outlog)
|
||||
return i;
|
||||
|
||||
pass = "within 8 bit limits:\n";
|
||||
}
|
||||
}
|
||||
# endif
|
||||
# endif
|
||||
}
|
||||
else /* !use_input_precision */
|
||||
|
|
@ -10001,9 +9886,12 @@ gamma_component_validate(const char *name, const validate_info *vi,
|
|||
case ALPHA_MODE_OFFSET + PNG_ALPHA_BROKEN:
|
||||
case ALPHA_MODE_OFFSET + PNG_ALPHA_OPTIMIZED:
|
||||
# endif /* ALPHA_MODE_SUPPORTED */
|
||||
# if (defined PNG_READ_BACKGROUND_SUPPORTED) ||\
|
||||
(defined PNG_READ_ALPHA_MODE_SUPPORTED)
|
||||
do_compose = (alpha > 0 && alpha < 1);
|
||||
use_input = (alpha != 0);
|
||||
break;
|
||||
# endif
|
||||
|
||||
default:
|
||||
break;
|
||||
|
|
@ -10649,16 +10537,21 @@ static void perform_gamma_transform_tests(png_modifier *pm)
|
|||
{
|
||||
unsigned int i, j;
|
||||
|
||||
for (i=0; i<pm->ngamma_tests; ++i) for (j=0; j<pm->ngamma_tests; ++j)
|
||||
if (i != j)
|
||||
for (i=0; i<pm->ngamma_tests; ++i)
|
||||
{
|
||||
for (j=0; j<pm->ngamma_tests; ++j)
|
||||
{
|
||||
gamma_transform_test(pm, colour_type, bit_depth, palette_number,
|
||||
pm->interlace_type, 1/pm->gammas[i], pm->gammas[j], 0/*sBIT*/,
|
||||
pm->use_input_precision, 0 /*do not scale16*/);
|
||||
if (i != j)
|
||||
{
|
||||
gamma_transform_test(pm, colour_type, bit_depth, palette_number,
|
||||
pm->interlace_type, 1/pm->gammas[i], pm->gammas[j],
|
||||
0/*sBIT*/, pm->use_input_precision, 0/*do not scale16*/);
|
||||
|
||||
if (fail(pm))
|
||||
return;
|
||||
if (fail(pm))
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -10687,14 +10580,17 @@ static void perform_gamma_sbit_tests(png_modifier *pm)
|
|||
{
|
||||
unsigned int j;
|
||||
|
||||
for (j=0; j<pm->ngamma_tests; ++j) if (i != j)
|
||||
for (j=0; j<pm->ngamma_tests; ++j)
|
||||
{
|
||||
gamma_transform_test(pm, colour_type, bit_depth, npalette,
|
||||
pm->interlace_type, 1/pm->gammas[i], pm->gammas[j],
|
||||
sbit, pm->use_input_precision_sbit, 0 /*scale16*/);
|
||||
if (i != j)
|
||||
{
|
||||
gamma_transform_test(pm, colour_type, bit_depth, npalette,
|
||||
pm->interlace_type, 1/pm->gammas[i], pm->gammas[j],
|
||||
sbit, pm->use_input_precision_sbit, 0 /*scale16*/);
|
||||
|
||||
if (fail(pm))
|
||||
return;
|
||||
if (fail(pm))
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -10711,7 +10607,7 @@ static void perform_gamma_scale16_tests(png_modifier *pm)
|
|||
# ifndef PNG_MAX_GAMMA_8
|
||||
# define PNG_MAX_GAMMA_8 11
|
||||
# endif
|
||||
# if defined PNG_MAX_GAMMA_8 || PNG_LIBPNG_VER < 10700
|
||||
# if defined PNG_MAX_GAMMA_8 || PNG_LIBPNG_VER != 10700
|
||||
# define SBIT_16_TO_8 PNG_MAX_GAMMA_8
|
||||
# else
|
||||
# define SBIT_16_TO_8 16
|
||||
|
|
@ -10946,14 +10842,17 @@ perform_gamma_composition_tests(png_modifier *pm, int do_background,
|
|||
unsigned int i, j;
|
||||
|
||||
/* Don't skip the i==j case here - it's relevant. */
|
||||
for (i=0; i<pm->ngamma_tests; ++i) for (j=0; j<pm->ngamma_tests; ++j)
|
||||
for (i=0; i<pm->ngamma_tests; ++i)
|
||||
{
|
||||
gamma_composition_test(pm, colour_type, bit_depth, palette_number,
|
||||
pm->interlace_type, 1/pm->gammas[i], pm->gammas[j],
|
||||
pm->use_input_precision, do_background, expand_16);
|
||||
for (j=0; j<pm->ngamma_tests; ++j)
|
||||
{
|
||||
gamma_composition_test(pm, colour_type, bit_depth, palette_number,
|
||||
pm->interlace_type, 1/pm->gammas[i], pm->gammas[j],
|
||||
pm->use_input_precision, do_background, expand_16);
|
||||
|
||||
if (fail(pm))
|
||||
return;
|
||||
if (fail(pm))
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -11056,7 +10955,7 @@ perform_gamma_test(png_modifier *pm, int summary)
|
|||
pm->calculations_use_input_precision = 0;
|
||||
|
||||
if (summary)
|
||||
summarize_gamma_errors(pm, 0/*who*/, 1/*low bit depth*/, 1/*indexed*/);
|
||||
summarize_gamma_errors(pm, NULL/*who*/, 1/*low bit depth*/, 1/*indexed*/);
|
||||
|
||||
if (fail(pm))
|
||||
return;
|
||||
|
|
@ -11182,8 +11081,10 @@ png_pass_start_row(int pass)
|
|||
{
|
||||
int x, y;
|
||||
++pass;
|
||||
for (y=0; y<8; ++y) for (x=0; x<8; ++x) if (adam7[y][x] == pass)
|
||||
return y;
|
||||
for (y=0; y<8; ++y)
|
||||
for (x=0; x<8; ++x)
|
||||
if (adam7[y][x] == pass)
|
||||
return y;
|
||||
return 0xf;
|
||||
}
|
||||
|
||||
|
|
@ -11192,8 +11093,10 @@ png_pass_start_col(int pass)
|
|||
{
|
||||
int x, y;
|
||||
++pass;
|
||||
for (x=0; x<8; ++x) for (y=0; y<8; ++y) if (adam7[y][x] == pass)
|
||||
return x;
|
||||
for (x=0; x<8; ++x)
|
||||
for (y=0; y<8; ++y)
|
||||
if (adam7[y][x] == pass)
|
||||
return x;
|
||||
return 0xf;
|
||||
}
|
||||
|
||||
|
|
@ -11202,18 +11105,24 @@ png_pass_row_shift(int pass)
|
|||
{
|
||||
int x, y, base=(-1), inc=8;
|
||||
++pass;
|
||||
for (y=0; y<8; ++y) for (x=0; x<8; ++x) if (adam7[y][x] == pass)
|
||||
for (y=0; y<8; ++y)
|
||||
{
|
||||
if (base == (-1))
|
||||
base = y;
|
||||
else if (base == y)
|
||||
{}
|
||||
else if (inc == y-base)
|
||||
base=y;
|
||||
else if (inc == 8)
|
||||
inc = y-base, base=y;
|
||||
else if (inc != y-base)
|
||||
return 0xff; /* error - more than one 'inc' value! */
|
||||
for (x=0; x<8; ++x)
|
||||
{
|
||||
if (adam7[y][x] == pass)
|
||||
{
|
||||
if (base == (-1))
|
||||
base = y;
|
||||
else if (base == y)
|
||||
{}
|
||||
else if (inc == y-base)
|
||||
base=y;
|
||||
else if (inc == 8)
|
||||
inc = y-base, base=y;
|
||||
else if (inc != y-base)
|
||||
return 0xff; /* error - more than one 'inc' value! */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (base == (-1)) return 0xfe; /* error - no row in pass! */
|
||||
|
|
@ -11236,18 +11145,24 @@ png_pass_col_shift(int pass)
|
|||
{
|
||||
int x, y, base=(-1), inc=8;
|
||||
++pass;
|
||||
for (x=0; x<8; ++x) for (y=0; y<8; ++y) if (adam7[y][x] == pass)
|
||||
for (x=0; x<8; ++x)
|
||||
{
|
||||
if (base == (-1))
|
||||
base = x;
|
||||
else if (base == x)
|
||||
{}
|
||||
else if (inc == x-base)
|
||||
base=x;
|
||||
else if (inc == 8)
|
||||
inc = x-base, base=x;
|
||||
else if (inc != x-base)
|
||||
return 0xff; /* error - more than one 'inc' value! */
|
||||
for (y=0; y<8; ++y)
|
||||
{
|
||||
if (adam7[y][x] == pass)
|
||||
{
|
||||
if (base == (-1))
|
||||
base = x;
|
||||
else if (base == x)
|
||||
{}
|
||||
else if (inc == x-base)
|
||||
base=x;
|
||||
else if (inc == 8)
|
||||
inc = x-base, base=x;
|
||||
else if (inc != x-base)
|
||||
return 0xff; /* error - more than one 'inc' value! */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (base == (-1)) return 0xfe; /* error - no row in pass! */
|
||||
|
|
@ -11311,8 +11226,9 @@ png_row_in_interlace_pass(png_uint_32 y, int pass)
|
|||
int x;
|
||||
y &= 7;
|
||||
++pass;
|
||||
for (x=0; x<8; ++x) if (adam7[y][x] == pass)
|
||||
return 1;
|
||||
for (x=0; x<8; ++x)
|
||||
if (adam7[y][x] == pass)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -11324,8 +11240,9 @@ png_col_in_interlace_pass(png_uint_32 x, int pass)
|
|||
int y;
|
||||
x &= 7;
|
||||
++pass;
|
||||
for (y=0; y<8; ++y) if (adam7[y][x] == pass)
|
||||
return 1;
|
||||
for (y=0; y<8; ++y)
|
||||
if (adam7[y][x] == pass)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -11339,11 +11256,17 @@ png_pass_rows(png_uint_32 height, int pass)
|
|||
|
||||
height &= 7;
|
||||
++pass;
|
||||
for (y=0; y<8; ++y) for (x=0; x<8; ++x) if (adam7[y][x] == pass)
|
||||
for (y=0; y<8; ++y)
|
||||
{
|
||||
rows += tiles;
|
||||
if (y < height) ++rows;
|
||||
break; /* i.e. break the 'x', column, loop. */
|
||||
for (x=0; x<8; ++x)
|
||||
{
|
||||
if (adam7[y][x] == pass)
|
||||
{
|
||||
rows += tiles;
|
||||
if (y < height) ++rows;
|
||||
break; /* i.e. break the 'x', column, loop. */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return rows;
|
||||
|
|
@ -11358,11 +11281,17 @@ png_pass_cols(png_uint_32 width, int pass)
|
|||
|
||||
width &= 7;
|
||||
++pass;
|
||||
for (x=0; x<8; ++x) for (y=0; y<8; ++y) if (adam7[y][x] == pass)
|
||||
for (x=0; x<8; ++x)
|
||||
{
|
||||
cols += tiles;
|
||||
if (x < width) ++cols;
|
||||
break; /* i.e. break the 'y', row, loop. */
|
||||
for (y=0; y<8; ++y)
|
||||
{
|
||||
if (adam7[y][x] == pass)
|
||||
{
|
||||
cols += tiles;
|
||||
if (x < width) ++cols;
|
||||
break; /* i.e. break the 'y', row, loop. */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return cols;
|
||||
|
|
@ -11681,7 +11610,7 @@ int main(int argc, char **argv)
|
|||
* code that 16-bit arithmetic is used for 8-bit samples when it would make a
|
||||
* difference.
|
||||
*/
|
||||
pm.assume_16_bit_calculations = PNG_LIBPNG_VER >= 10700;
|
||||
pm.assume_16_bit_calculations = PNG_LIBPNG_VER == 10700;
|
||||
|
||||
/* Currently 16 bit expansion happens at the end of the pipeline, so the
|
||||
* calculations are done in the input bit depth not the output.
|
||||
|
|
@ -11701,17 +11630,17 @@ int main(int argc, char **argv)
|
|||
# ifdef PNG_WRITE_tRNS_SUPPORTED
|
||||
pm.test_tRNS = 1;
|
||||
# endif
|
||||
pm.test_lbg = PNG_LIBPNG_VER >= 10600;
|
||||
pm.test_lbg = 1; /* PNG_LIBPNG_VER >= 10600 */
|
||||
pm.test_lbg_gamma_threshold = 1;
|
||||
pm.test_lbg_gamma_transform = PNG_LIBPNG_VER >= 10600;
|
||||
pm.test_lbg_gamma_transform = 1; /* PNG_LIBPNG_VER >= 10600 */
|
||||
pm.test_lbg_gamma_sbit = 1;
|
||||
pm.test_lbg_gamma_composition = PNG_LIBPNG_VER >= 10700;
|
||||
pm.test_lbg_gamma_composition = PNG_LIBPNG_VER == 10700;
|
||||
|
||||
/* And the test encodings */
|
||||
pm.encodings = test_encodings;
|
||||
pm.nencodings = ARRAY_SIZE(test_encodings);
|
||||
|
||||
# if PNG_LIBPNG_VER < 10700
|
||||
# if PNG_LIBPNG_VER != 10700
|
||||
pm.sbitlow = 8U; /* because libpng doesn't do sBIT below 8! */
|
||||
# else
|
||||
pm.sbitlow = 1U;
|
||||
|
|
@ -11719,7 +11648,7 @@ int main(int argc, char **argv)
|
|||
|
||||
/* The following allows results to pass if they correspond to anything in the
|
||||
* transformed range [input-.5,input+.5]; this is is required because of the
|
||||
* way libpng treates the 16_TO_8 flag when building the gamma tables in
|
||||
* way libpng treats the 16_TO_8 flag when building the gamma tables in
|
||||
* releases up to 1.6.0.
|
||||
*
|
||||
* TODO: review this
|
||||
|
|
@ -11741,7 +11670,7 @@ int main(int argc, char **argv)
|
|||
pm.maxout16 = .499; /* Error in *encoded* value */
|
||||
pm.maxabs16 = .00005;/* 1/20000 */
|
||||
pm.maxcalc16 =1./65535;/* +/-1 in 16 bits for compose errors */
|
||||
# if PNG_LIBPNG_VER < 10700
|
||||
# if PNG_LIBPNG_VER != 10700
|
||||
pm.maxcalcG = 1./((1<<PNG_MAX_GAMMA_8)-1);
|
||||
# else
|
||||
pm.maxcalcG = 1./((1<<16)-1);
|
||||
|
|
@ -11810,21 +11739,21 @@ int main(int argc, char **argv)
|
|||
#ifdef PNG_READ_TRANSFORMS_SUPPORTED
|
||||
else if (strncmp(*argv, "--transform-disable=",
|
||||
sizeof "--transform-disable") == 0)
|
||||
{
|
||||
{
|
||||
pm.test_transform = 1;
|
||||
transform_disable(*argv + sizeof "--transform-disable");
|
||||
}
|
||||
}
|
||||
|
||||
else if (strncmp(*argv, "--transform-enable=",
|
||||
sizeof "--transform-enable") == 0)
|
||||
{
|
||||
{
|
||||
pm.test_transform = 1;
|
||||
transform_enable(*argv + sizeof "--transform-enable");
|
||||
}
|
||||
}
|
||||
#endif /* PNG_READ_TRANSFORMS_SUPPORTED */
|
||||
|
||||
else if (strcmp(*argv, "--gamma") == 0)
|
||||
{
|
||||
{
|
||||
/* Just do two gamma tests here (2.2 and linear) for speed: */
|
||||
pm.ngamma_tests = 2U;
|
||||
pm.test_gamma_threshold = 1;
|
||||
|
|
@ -11833,7 +11762,7 @@ int main(int argc, char **argv)
|
|||
pm.test_gamma_scale16 = 1;
|
||||
pm.test_gamma_background = 1; /* composition */
|
||||
pm.test_gamma_alpha_mode = 1;
|
||||
}
|
||||
}
|
||||
|
||||
else if (strcmp(*argv, "--nogamma") == 0)
|
||||
pm.ngamma_tests = 0;
|
||||
|
|
@ -11875,7 +11804,14 @@ int main(int argc, char **argv)
|
|||
pm.test_gamma_alpha_mode = 0;
|
||||
|
||||
else if (strcmp(*argv, "--expand16") == 0)
|
||||
pm.test_gamma_expand16 = 1;
|
||||
{
|
||||
# ifdef PNG_READ_EXPAND_16_SUPPORTED
|
||||
pm.test_gamma_expand16 = 1;
|
||||
# else
|
||||
fprintf(stderr, "pngvalid: --expand16: no read support\n");
|
||||
return SKIP;
|
||||
# endif
|
||||
}
|
||||
|
||||
else if (strcmp(*argv, "--noexpand16") == 0)
|
||||
pm.test_gamma_expand16 = 0;
|
||||
|
|
@ -11890,10 +11826,15 @@ int main(int argc, char **argv)
|
|||
pm.test_lbg_gamma_transform = pm.test_lbg_gamma_sbit =
|
||||
pm.test_lbg_gamma_composition = 0;
|
||||
|
||||
# ifdef PNG_WRITE_tRNS_SUPPORTED
|
||||
else if (strcmp(*argv, "--tRNS") == 0)
|
||||
else if (strcmp(*argv, "--tRNS") == 0)
|
||||
{
|
||||
# ifdef PNG_WRITE_tRNS_SUPPORTED
|
||||
pm.test_tRNS = 1;
|
||||
# endif
|
||||
# else
|
||||
fprintf(stderr, "pngvalid: --tRNS: no write support\n");
|
||||
return SKIP;
|
||||
# endif
|
||||
}
|
||||
|
||||
else if (strcmp(*argv, "--notRNS") == 0)
|
||||
pm.test_tRNS = 0;
|
||||
|
|
@ -12147,7 +12088,7 @@ int main(int argc, char **argv)
|
|||
(pm.this.nerrors || (pm.this.treat_warnings_as_errors &&
|
||||
pm.this.nwarnings)) ? "FAIL" : "PASS",
|
||||
command,
|
||||
#if defined(PNG_FLOATING_ARITHMETIC_SUPPORTED) || PNG_LIBPNG_VER < 10500
|
||||
#if defined(PNG_FLOATING_ARITHMETIC_SUPPORTED)
|
||||
"floating"
|
||||
#else
|
||||
"fixed"
|
||||
|
|
|
|||
|
|
@ -2,8 +2,6 @@
|
|||
*
|
||||
* Copyright (c) 2013 John Cunningham Bowler
|
||||
*
|
||||
* Last changed in libpng 1.6.1 [March 28, 2013]
|
||||
*
|
||||
* This code is released under the libpng license.
|
||||
* For conditions of distribution and use, see the disclaimer
|
||||
* and license in png.h
|
||||
|
|
|
|||
|
|
@ -1,10 +1,8 @@
|
|||
|
||||
/* tarith.c
|
||||
*
|
||||
* Copyright (c) 2021 Cosmin Truta
|
||||
* Copyright (c) 2011-2013 John Cunningham Bowler
|
||||
*
|
||||
* Last changed in libpng 1.6.0 [February 14, 2013]
|
||||
*
|
||||
* This code is released under the libpng license.
|
||||
* For conditions of distribution and use, see the disclaimer
|
||||
* and license in png.h
|
||||
|
|
@ -88,6 +86,7 @@ int validation_ascii_to_fp(int count, int argc, char **argv)
|
|||
int minorarith = 0;
|
||||
|
||||
while (--argc > 0)
|
||||
{
|
||||
if (strcmp(*++argv, "-a") == 0)
|
||||
showall = 1;
|
||||
else if (strcmp(*argv, "-e") == 0 && argc > 0)
|
||||
|
|
@ -105,6 +104,7 @@ int validation_ascii_to_fp(int count, int argc, char **argv)
|
|||
fprintf(stderr, "unknown argument %s\n", *argv);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
|
|
@ -130,8 +130,8 @@ int validation_ascii_to_fp(int count, int argc, char **argv)
|
|||
*/
|
||||
if (buffer[precision+7] != 71)
|
||||
{
|
||||
fprintf(stderr, "%g[%d] -> '%s'[%lu] buffer overflow\n", test,
|
||||
precision, buffer, (unsigned long)strlen(buffer));
|
||||
fprintf(stderr, "%g[%d] -> '%s'[%lu] buffer overflow\n",
|
||||
test, precision, buffer, (unsigned long)strlen(buffer));
|
||||
failed = 1;
|
||||
}
|
||||
|
||||
|
|
@ -146,16 +146,16 @@ int validation_ascii_to_fp(int count, int argc, char **argv)
|
|||
if (test >= 0 && strcmp(buffer, "inf") ||
|
||||
test < 0 && strcmp(buffer, "-inf"))
|
||||
{
|
||||
fprintf(stderr, "%g[%d] -> '%s' but expected 'inf'\n", test,
|
||||
precision, buffer);
|
||||
fprintf(stderr, "%g[%d] -> '%s' but expected 'inf'\n",
|
||||
test, precision, buffer);
|
||||
failed = 1;
|
||||
}
|
||||
}
|
||||
else if (!png_check_fp_number(buffer, precision+10, &state, &index) ||
|
||||
buffer[index] != 0)
|
||||
{
|
||||
fprintf(stderr, "%g[%d] -> '%s' but has bad format ('%c')\n", test,
|
||||
precision, buffer, buffer[index]);
|
||||
fprintf(stderr, "%g[%d] -> '%s' but has bad format ('%c')\n",
|
||||
test, precision, buffer, buffer[index]);
|
||||
failed = 1;
|
||||
}
|
||||
else if (PNG_FP_IS_NEGATIVE(state) && !(test < 0))
|
||||
|
|
@ -187,7 +187,7 @@ int validation_ascii_to_fp(int count, int argc, char **argv)
|
|||
/* Check the result against the original. */
|
||||
double out = atof(buffer);
|
||||
double change = fabs((out - test)/test);
|
||||
double allow = .5/pow(10,
|
||||
double allow = .5 / pow(10,
|
||||
(precision >= DBL_DIG) ? DBL_DIG-1 : precision-1);
|
||||
|
||||
/* NOTE: if you hit this error case are you compiling with gcc
|
||||
|
|
@ -257,8 +257,9 @@ skip:
|
|||
}
|
||||
while (--count);
|
||||
|
||||
printf("Tested %d finite values, %d non-finite, %d OK (%d failed) %d minor "
|
||||
"arithmetic errors\n", finite, nonfinite, ok, failcount, minorarith);
|
||||
printf("Tested %d finite values, %d non-finite, %d OK (%d failed) "
|
||||
"%d minor arithmetic errors\n",
|
||||
finite, nonfinite, ok, failcount, minorarith);
|
||||
printf(" Error with >=%d digit precision %.2f%%\n", DBL_DIG, max_abs);
|
||||
printf(" Error with < %d digit precision %.2f%%\n", DBL_DIG, max);
|
||||
|
||||
|
|
@ -371,8 +372,8 @@ static int check_one_character(checkfp_command *co, checkfp_control c, int ch)
|
|||
/* This should never fail (it's a serious bug if it does): */
|
||||
if (index != 0 && index != 1)
|
||||
{
|
||||
fprintf(stderr, "%s: read beyond end of string (%lu)\n", co->number,
|
||||
(unsigned long)index);
|
||||
fprintf(stderr, "%s: read beyond end of string (%lu)\n",
|
||||
co->number, (unsigned long)index);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -503,8 +504,8 @@ static int check_one_character(checkfp_command *co, checkfp_control c, int ch)
|
|||
if (number_is_valid != c.number_was_valid)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"%s: character '%c' [0x%.2x] changed number validity\n", co->number,
|
||||
ch, ch);
|
||||
"%s: character '%c' [0x%.2x] changed number validity\n",
|
||||
co->number, ch, ch);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -521,10 +522,13 @@ static int check_all_characters(checkfp_command *co, checkfp_control c)
|
|||
{
|
||||
int ch;
|
||||
|
||||
if (c.cnumber+4 < sizeof co->number) for (ch=0; ch<256; ++ch)
|
||||
if (c.cnumber+4 < sizeof co->number)
|
||||
{
|
||||
if (!check_one_character(co, c, ch))
|
||||
return 0;
|
||||
for (ch=0; ch<256; ++ch)
|
||||
{
|
||||
if (!check_one_character(co, c, ch))
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
|
@ -539,10 +543,13 @@ static int check_some_characters(checkfp_command *co, checkfp_control c,
|
|||
|
||||
if (c.cnumber+4 < sizeof co->number && c.limit >= 0)
|
||||
{
|
||||
if (c.limit > 0) for (i=0; tests[i]; ++i)
|
||||
if (c.limit > 0)
|
||||
{
|
||||
if (!check_one_character(co, c, tests[i]))
|
||||
return 0;
|
||||
for (i=0; tests[i]; ++i)
|
||||
{
|
||||
if (!check_one_character(co, c, tests[i]))
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* At the end check all the characters. */
|
||||
|
|
@ -616,10 +623,10 @@ int validation_muldiv(int count, int argc, char **argv)
|
|||
png_int_32 times, div;
|
||||
|
||||
while (--argc > 0)
|
||||
{
|
||||
fprintf(stderr, "unknown argument %s\n", *++argv);
|
||||
return 1;
|
||||
}
|
||||
{
|
||||
fprintf(stderr, "unknown argument %s\n", *++argv);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Find out about the random number generator. */
|
||||
randbuffer = RAND_MAX;
|
||||
|
|
@ -687,25 +694,25 @@ int validation_muldiv(int count, int argc, char **argv)
|
|||
ok = 0, ++overflow, fpround = fp/*misleading*/;
|
||||
|
||||
if (verbose)
|
||||
fprintf(stderr, "TEST %d * %d / %d -> %lld (%s)\n", a, times, div,
|
||||
fp, ok ? "ok" : "overflow");
|
||||
fprintf(stderr, "TEST %d * %d / %d -> %lld (%s)\n",
|
||||
a, times, div, fp, ok ? "ok" : "overflow");
|
||||
|
||||
++tested;
|
||||
if (png_muldiv(&result, a, times, div) != ok)
|
||||
{
|
||||
++error;
|
||||
if (ok)
|
||||
fprintf(stderr, "%d * %d / %d -> overflow (expected %lld)\n", a,
|
||||
times, div, fp);
|
||||
fprintf(stderr, "%d * %d / %d -> overflow (expected %lld)\n",
|
||||
a, times, div, fp);
|
||||
else
|
||||
fprintf(stderr, "%d * %d / %d -> %d (expected overflow %lld)\n", a,
|
||||
times, div, result, fp);
|
||||
fprintf(stderr, "%d * %d / %d -> %d (expected overflow %lld)\n",
|
||||
a, times, div, result, fp);
|
||||
}
|
||||
else if (ok && result != fpround)
|
||||
{
|
||||
++error;
|
||||
fprintf(stderr, "%d * %d / %d -> %d not %lld\n", a, times, div, result,
|
||||
fp);
|
||||
fprintf(stderr, "%d * %d / %d -> %d not %lld\n",
|
||||
a, times, div, result, fp);
|
||||
}
|
||||
else
|
||||
++passed;
|
||||
|
|
@ -721,8 +728,8 @@ int validation_muldiv(int count, int argc, char **argv)
|
|||
}
|
||||
while (--count > 0);
|
||||
|
||||
printf("%d tests including %d overflows, %d passed, %d failed (%d 64-bit "
|
||||
"errors)\n", tested, overflow, passed, error, error64);
|
||||
printf("%d tests including %d overflows, %d passed, %d failed "
|
||||
"(%d 64-bit errors)\n", tested, overflow, passed, error, error64);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -821,8 +828,9 @@ int validation_gamma(int argc, char **argv)
|
|||
{
|
||||
if (error > .68) /* By experiment error is less than .68 */
|
||||
{
|
||||
fprintf(stderr, "16-bit log error: %d: got %u, expected %f"
|
||||
" error: %f\n", i, png_log16bit(i), correct, error);
|
||||
fprintf(stderr,
|
||||
"16-bit log error: %d: got %u, expected %f error: %f\n",
|
||||
i, png_log16bit(i), correct, error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -841,8 +849,9 @@ int validation_gamma(int argc, char **argv)
|
|||
maxerr = fabs(error);
|
||||
if (fabs(error) > 1883) /* By experiment. */
|
||||
{
|
||||
fprintf(stderr, "32-bit exp error: %d: got %u, expected %f"
|
||||
" error: %f\n", i, png_exp(i), correct, error);
|
||||
fprintf(stderr,
|
||||
"32-bit exp error: %d: got %u, expected %f error: %f\n",
|
||||
i, png_exp(i), correct, error);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -859,8 +868,9 @@ int validation_gamma(int argc, char **argv)
|
|||
maxerr = fabs(error);
|
||||
if (fabs(error) > .50002) /* By experiment */
|
||||
{
|
||||
fprintf(stderr, "8-bit exp error: %d: got %u, expected %f"
|
||||
" error: %f\n", i, png_exp8bit(i), correct, error);
|
||||
fprintf(stderr,
|
||||
"8-bit exp error: %d: got %u, expected %f error: %f\n",
|
||||
i, png_exp8bit(i), correct, error);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -877,8 +887,9 @@ int validation_gamma(int argc, char **argv)
|
|||
maxerr = fabs(error);
|
||||
if (fabs(error) > .524) /* By experiment */
|
||||
{
|
||||
fprintf(stderr, "16-bit exp error: %d: got %u, expected %f"
|
||||
" error: %f\n", i, png_exp16bit(i), correct, error);
|
||||
fprintf(stderr,
|
||||
"16-bit exp error: %d: got %u, expected %f error: %f\n",
|
||||
i, png_exp16bit(i), correct, error);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -940,7 +951,7 @@ int validation_gamma(int argc, char **argv)
|
|||
|
||||
/**************************** VALIDATION TESTS ********************************/
|
||||
/* Various validation routines are included herein, they require some
|
||||
* definition for png_warning and png_error, seetings of VALIDATION:
|
||||
* definition for png_warning and png_error, settings of VALIDATION:
|
||||
*
|
||||
* 1: validates the ASCII to floating point conversions
|
||||
* 2: validates png_muldiv
|
||||
|
|
|
|||
|
|
@ -2,8 +2,6 @@
|
|||
*
|
||||
* Copyright (c) 2013,2016 John Cunningham Bowler
|
||||
*
|
||||
* Last changed in libpng 1.6.22 [May 26, 2016]
|
||||
*
|
||||
* This code is released under the libpng license.
|
||||
* For conditions of distribution and use, see the disclaimer
|
||||
* and license in png.h
|
||||
|
|
@ -528,7 +526,7 @@ int main(int argc, char **argv)
|
|||
}
|
||||
}
|
||||
|
||||
else if (nfiles == 0) /* Read from stdin withoout --dissemble */
|
||||
else if (nfiles == 0) /* Read from stdin without --dissemble */
|
||||
{
|
||||
char filename[FILENAME_MAX+1];
|
||||
|
||||
|
|
|
|||
141
Engine/lib/lpng/contrib/mips-mmi/linux.c
Normal file
|
|
@ -0,0 +1,141 @@
|
|||
/* contrib/mips-mmi/linux.c
|
||||
*
|
||||
* Copyright (c) 2024 Cosmin Truta
|
||||
* Written by guxiwei, 2023
|
||||
*
|
||||
* This code is released under the libpng license.
|
||||
* For conditions of distribution and use, see the disclaimer
|
||||
* and license in png.h
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/auxv.h>
|
||||
|
||||
/*
|
||||
* parse_r var, r - Helper assembler macro for parsing register names.
|
||||
*
|
||||
* This converts the register name in $n form provided in \r to the
|
||||
* corresponding register number, which is assigned to the variable \var. It is
|
||||
* needed to allow explicit encoding of instructions in inline assembly where
|
||||
* registers are chosen by the compiler in $n form, allowing us to avoid using
|
||||
* fixed register numbers.
|
||||
*
|
||||
* It also allows newer instructions (not implemented by the assembler) to be
|
||||
* transparently implemented using assembler macros, instead of needing separate
|
||||
* cases depending on toolchain support.
|
||||
*
|
||||
* Simple usage example:
|
||||
* __asm__ __volatile__("parse_r __rt, %0\n\t"
|
||||
* ".insn\n\t"
|
||||
* "# di %0\n\t"
|
||||
* ".word (0x41606000 | (__rt << 16))"
|
||||
* : "=r" (status);
|
||||
*/
|
||||
|
||||
/* Match an individual register number and assign to \var */
|
||||
#define _IFC_REG(n) \
|
||||
".ifc \\r, $" #n "\n\t" \
|
||||
"\\var = " #n "\n\t" \
|
||||
".endif\n\t"
|
||||
|
||||
__asm__(".macro parse_r var r\n\t"
|
||||
"\\var = -1\n\t"
|
||||
_IFC_REG(0) _IFC_REG(1) _IFC_REG(2) _IFC_REG(3)
|
||||
_IFC_REG(4) _IFC_REG(5) _IFC_REG(6) _IFC_REG(7)
|
||||
_IFC_REG(8) _IFC_REG(9) _IFC_REG(10) _IFC_REG(11)
|
||||
_IFC_REG(12) _IFC_REG(13) _IFC_REG(14) _IFC_REG(15)
|
||||
_IFC_REG(16) _IFC_REG(17) _IFC_REG(18) _IFC_REG(19)
|
||||
_IFC_REG(20) _IFC_REG(21) _IFC_REG(22) _IFC_REG(23)
|
||||
_IFC_REG(24) _IFC_REG(25) _IFC_REG(26) _IFC_REG(27)
|
||||
_IFC_REG(28) _IFC_REG(29) _IFC_REG(30) _IFC_REG(31)
|
||||
".iflt \\var\n\t"
|
||||
".error \"Unable to parse register name \\r\"\n\t"
|
||||
".endif\n\t"
|
||||
".endm");
|
||||
|
||||
#define HWCAP_LOONGSON_CPUCFG (1 << 14)
|
||||
|
||||
static int cpucfg_available(void)
|
||||
{
|
||||
return getauxval(AT_HWCAP) & HWCAP_LOONGSON_CPUCFG;
|
||||
}
|
||||
|
||||
static int strstart(const char *str, const char *pfx, const char **ptr)
|
||||
{
|
||||
while (*pfx && *pfx == *str) {
|
||||
pfx++;
|
||||
str++;
|
||||
}
|
||||
if (!*pfx && ptr)
|
||||
*ptr = str;
|
||||
return !*pfx;
|
||||
}
|
||||
|
||||
/* Most toolchains have no CPUCFG support yet */
|
||||
static uint32_t read_cpucfg(uint32_t reg)
|
||||
{
|
||||
uint32_t __res;
|
||||
|
||||
__asm__ __volatile__(
|
||||
"parse_r __res,%0\n\t"
|
||||
"parse_r reg,%1\n\t"
|
||||
".insn \n\t"
|
||||
".word (0xc8080118 | (reg << 21) | (__res << 11))\n\t"
|
||||
:"=r"(__res)
|
||||
:"r"(reg)
|
||||
:
|
||||
);
|
||||
return __res;
|
||||
}
|
||||
|
||||
#define LOONGSON_CFG1 0x1
|
||||
|
||||
#define LOONGSON_CFG1_MMI (1 << 4)
|
||||
|
||||
static int cpu_flags_cpucfg(void)
|
||||
{
|
||||
int flags = 0;
|
||||
uint32_t cfg1 = read_cpucfg(LOONGSON_CFG1);
|
||||
|
||||
if (cfg1 & LOONGSON_CFG1_MMI)
|
||||
flags = 1;
|
||||
|
||||
return flags;
|
||||
}
|
||||
|
||||
static int cpu_flags_cpuinfo(void)
|
||||
{
|
||||
FILE *f = fopen("/proc/cpuinfo", "r");
|
||||
char buf[200];
|
||||
int flags = 0;
|
||||
|
||||
if (!f)
|
||||
return flags;
|
||||
|
||||
while (fgets(buf, sizeof(buf), f)) {
|
||||
/* Legacy kernel may not export MMI in ASEs implemented */
|
||||
if (strstart(buf, "cpu model", NULL)) {
|
||||
if (strstr(buf, "Loongson-3 "))
|
||||
flags = 1;
|
||||
break;
|
||||
}
|
||||
if (strstart(buf, "ASEs implemented", NULL)) {
|
||||
if (strstr(buf, " loongson-mmi"))
|
||||
flags = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
fclose(f);
|
||||
return flags;
|
||||
}
|
||||
|
||||
static int png_have_mmi()
|
||||
{
|
||||
if (cpucfg_available())
|
||||
return cpu_flags_cpucfg();
|
||||
else
|
||||
return cpu_flags_cpuinfo();
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1,64 +1,54 @@
|
|||
/* contrib/mips-msa/linux.c
|
||||
*
|
||||
* Copyright (c) 2020-2023 Cosmin Truta
|
||||
* Copyright (c) 2016 Glenn Randers-Pehrson
|
||||
* Written by Mandar Sahastrabuddhe, 2016.
|
||||
* Last changed in libpng 1.6.25beta03 [August 29, 2016]
|
||||
* Updated by Sui Jingfeng, 2021.
|
||||
*
|
||||
* This code is released under the libpng license.
|
||||
* For conditions of distribution and use, see the disclaimer
|
||||
* and license in png.h
|
||||
*
|
||||
* SEE contrib/mips-msa/README before reporting bugs
|
||||
* On Linux, png_have_msa is implemented by reading the pseudo-file
|
||||
* "/proc/self/auxv".
|
||||
*
|
||||
* See contrib/mips-msa/README before reporting bugs.
|
||||
*
|
||||
* STATUS: SUPPORTED
|
||||
* BUG REPORTS: png-mng-implement@sourceforge.net
|
||||
*
|
||||
* png_have_msa implemented for Linux by reading the widely available
|
||||
* pseudo-file /proc/cpuinfo.
|
||||
*
|
||||
* This code is strict ANSI-C and is probably moderately portable; it does
|
||||
* however use <stdio.h> and it assumes that /proc/cpuinfo is never localized.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <elf.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
static int
|
||||
png_have_msa(png_structp png_ptr)
|
||||
{
|
||||
FILE *f = fopen("/proc/cpuinfo", "rb");
|
||||
Elf64_auxv_t aux;
|
||||
int fd;
|
||||
int has_msa = 0;
|
||||
|
||||
char *string = "msa";
|
||||
char word[10];
|
||||
|
||||
if (f != NULL)
|
||||
fd = open("/proc/self/auxv", O_RDONLY);
|
||||
if (fd >= 0)
|
||||
{
|
||||
while(!feof(f))
|
||||
while (read(fd, &aux, sizeof(Elf64_auxv_t)) == sizeof(Elf64_auxv_t))
|
||||
{
|
||||
int ch = fgetc(f);
|
||||
static int i = 0;
|
||||
|
||||
while(!(ch <= 32))
|
||||
if (aux.a_type == AT_HWCAP)
|
||||
{
|
||||
word[i++] = ch;
|
||||
ch = fgetc(f);
|
||||
uint64_t hwcap = aux.a_un.a_val;
|
||||
|
||||
has_msa = (hwcap >> 1) & 1;
|
||||
break;
|
||||
}
|
||||
|
||||
int val = strcmp(string, word);
|
||||
|
||||
if (val == 0)
|
||||
return 1;
|
||||
|
||||
i = 0;
|
||||
memset(word, 0, 10);
|
||||
}
|
||||
|
||||
fclose(f);
|
||||
close(fd);
|
||||
}
|
||||
#ifdef PNG_WARNINGS_SUPPORTED
|
||||
else
|
||||
png_warning(png_ptr, "/proc/cpuinfo open failed");
|
||||
png_warning(png_ptr, "/proc/self/auxv open failed");
|
||||
#endif
|
||||
return 0;
|
||||
|
||||
return has_msa;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
Last changed in libpng 1.6.33 [September 28, 2017]
|
||||
Copyright (c) 2017 Glenn Randers-Pehrson
|
||||
|
||||
This code is released under the libpng license.
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
#!/bin/bash -eu
|
||||
|
||||
# Copyright 2017-2018 Glenn Randers-Pehrson
|
||||
# Copyright 2016 Google Inc.
|
||||
#
|
||||
|
|
@ -14,8 +15,6 @@
|
|||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
# Last changed in libpng 1.6.35 [July 15, 2018]
|
||||
#
|
||||
# Revisions by Glenn Randers-Pehrson, 2017:
|
||||
# 1. Build only the library, not the tools (changed "make -j$(nproc) all" to
|
||||
# "make -j$(nproc) libpng16.la").
|
||||
|
|
|
|||
|
|
@ -1,12 +1,9 @@
|
|||
|
||||
// libpng_read_fuzzer.cc
|
||||
// Copyright 2017-2018 Glenn Randers-Pehrson
|
||||
// Copyright 2015 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that may
|
||||
// be found in the LICENSE file https://cs.chromium.org/chromium/src/LICENSE
|
||||
|
||||
// Last changed in libpng 1.6.35 [July 15, 2018]
|
||||
|
||||
// The modifications in 2017 by Glenn Randers-Pehrson include
|
||||
// 1. addition of a PNG_CLEANUP macro,
|
||||
// 2. setting the option to ignore ADLER32 checksums,
|
||||
|
|
@ -17,14 +14,17 @@
|
|||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <vector>
|
||||
|
||||
#define PNG_INTERNAL
|
||||
#include "png.h"
|
||||
#include "nalloc.h"
|
||||
|
||||
#define PNG_CLEANUP \
|
||||
nalloc_end(); \
|
||||
if(png_handler.png_ptr) \
|
||||
{ \
|
||||
if (png_handler.row_ptr) \
|
||||
|
|
@ -60,7 +60,7 @@ struct PngObjectHandler {
|
|||
png_free(png_ptr, row_ptr);
|
||||
if (end_info_ptr)
|
||||
png_destroy_read_struct(&png_ptr, &info_ptr, &end_info_ptr);
|
||||
else if (info_ptr)
|
||||
else if (info_ptr)
|
||||
png_destroy_read_struct(&png_ptr, &info_ptr, nullptr);
|
||||
else
|
||||
png_destroy_read_struct(&png_ptr, nullptr, nullptr);
|
||||
|
|
@ -78,6 +78,22 @@ void user_read_data(png_structp png_ptr, png_bytep data, size_t length) {
|
|||
buf_state->data += length;
|
||||
}
|
||||
|
||||
void* limited_malloc(png_structp, png_alloc_size_t size) {
|
||||
// libpng may allocate large amounts of memory that the fuzzer reports as
|
||||
// an error. In order to silence these errors, make libpng fail when trying
|
||||
// to allocate a large amount. This allocator used to be in the Chromium
|
||||
// version of this fuzzer.
|
||||
// This number is chosen to match the default png_user_chunk_malloc_max.
|
||||
if (size > 8000000)
|
||||
return nullptr;
|
||||
|
||||
return malloc(size);
|
||||
}
|
||||
|
||||
void default_free(png_structp, png_voidp ptr) {
|
||||
return free(ptr);
|
||||
}
|
||||
|
||||
static const int kPngHeaderSize = 8;
|
||||
|
||||
// Entry point for LibFuzzer.
|
||||
|
|
@ -87,6 +103,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
|
|||
if (size < kPngHeaderSize) {
|
||||
return 0;
|
||||
}
|
||||
nalloc_init(nullptr);
|
||||
|
||||
std::vector<unsigned char> v(data, data + size);
|
||||
if (png_sig_cmp(v.data(), 0, kPngHeaderSize)) {
|
||||
|
|
@ -106,6 +123,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
nalloc_start(data, size);
|
||||
png_handler.info_ptr = png_create_info_struct(png_handler.png_ptr);
|
||||
if (!png_handler.info_ptr) {
|
||||
PNG_CLEANUP
|
||||
|
|
@ -118,6 +136,9 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
// Use a custom allocator that fails for large allocations to avoid OOM.
|
||||
png_set_mem_fn(png_handler.png_ptr, nullptr, limited_malloc, default_free);
|
||||
|
||||
png_set_crc_action(png_handler.png_ptr, PNG_CRC_QUIET_USE, PNG_CRC_QUIET_USE);
|
||||
#ifdef PNG_IGNORE_ADLER32
|
||||
png_set_option(png_handler.png_ptr, PNG_IGNORE_ADLER32, PNG_OPTION_ON);
|
||||
|
|
@ -186,5 +207,21 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
|
|||
png_read_end(png_handler.png_ptr, png_handler.end_info_ptr);
|
||||
|
||||
PNG_CLEANUP
|
||||
|
||||
#ifdef PNG_SIMPLIFIED_READ_SUPPORTED
|
||||
// Simplified READ API
|
||||
png_image image;
|
||||
memset(&image, 0, (sizeof image));
|
||||
image.version = PNG_IMAGE_VERSION;
|
||||
|
||||
if (!png_image_begin_read_from_memory(&image, data, size)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
image.format = PNG_FORMAT_RGBA;
|
||||
std::vector<png_byte> buffer(PNG_IMAGE_SIZE(image));
|
||||
png_image_finish_read(&image, NULL, buffer.data(), 0, NULL);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
330
Engine/lib/lpng/contrib/oss-fuzz/nalloc.h
Normal file
|
|
@ -0,0 +1,330 @@
|
|||
/*
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2025 Catena cyber
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef NALLOC_H_
|
||||
#define NALLOC_H_
|
||||
|
||||
#if defined(__clang__) && defined(__has_feature)
|
||||
#if __has_feature(address_sanitizer)
|
||||
#define NALLOC_ASAN 1
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
static const uint32_t nalloc_crc32_table[] = {
|
||||
0x00000000, 0x04c11db7, 0x09823b6e, 0x0d4326d9, 0x130476dc, 0x17c56b6b,
|
||||
0x1a864db2, 0x1e475005, 0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, 0x2b4bcb61,
|
||||
0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd, 0x4c11db70, 0x48d0c6c7,
|
||||
0x4593e01e, 0x4152fda9, 0x5f15adac, 0x5bd4b01b, 0x569796c2, 0x52568b75,
|
||||
0x6a1936c8, 0x6ed82b7f, 0x639b0da6, 0x675a1011, 0x791d4014, 0x7ddc5da3,
|
||||
0x709f7b7a, 0x745e66cd, 0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039,
|
||||
0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5, 0xbe2b5b58, 0xbaea46ef,
|
||||
0xb7a96036, 0xb3687d81, 0xad2f2d84, 0xa9ee3033, 0xa4ad16ea, 0xa06c0b5d,
|
||||
0xd4326d90, 0xd0f37027, 0xddb056fe, 0xd9714b49, 0xc7361b4c, 0xc3f706fb,
|
||||
0xceb42022, 0xca753d95, 0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1,
|
||||
0xe13ef6f4, 0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d, 0x34867077, 0x30476dc0,
|
||||
0x3d044b19, 0x39c556ae, 0x278206ab, 0x23431b1c, 0x2e003dc5, 0x2ac12072,
|
||||
0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16, 0x018aeb13, 0x054bf6a4,
|
||||
0x0808d07d, 0x0cc9cdca, 0x7897ab07, 0x7c56b6b0, 0x71159069, 0x75d48dde,
|
||||
0x6b93dddb, 0x6f52c06c, 0x6211e6b5, 0x66d0fb02, 0x5e9f46bf, 0x5a5e5b08,
|
||||
0x571d7dd1, 0x53dc6066, 0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba,
|
||||
0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e, 0xbfa1b04b, 0xbb60adfc,
|
||||
0xb6238b25, 0xb2e29692, 0x8aad2b2f, 0x8e6c3698, 0x832f1041, 0x87ee0df6,
|
||||
0x99a95df3, 0x9d684044, 0x902b669d, 0x94ea7b2a, 0xe0b41de7, 0xe4750050,
|
||||
0xe9362689, 0xedf73b3e, 0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2,
|
||||
0xc6bcf05f, 0xc27dede8, 0xcf3ecb31, 0xcbffd686, 0xd5b88683, 0xd1799b34,
|
||||
0xdc3abded, 0xd8fba05a, 0x690ce0ee, 0x6dcdfd59, 0x608edb80, 0x644fc637,
|
||||
0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb, 0x4f040d56, 0x4bc510e1,
|
||||
0x46863638, 0x42472b8f, 0x5c007b8a, 0x58c1663d, 0x558240e4, 0x51435d53,
|
||||
0x251d3b9e, 0x21dc2629, 0x2c9f00f0, 0x285e1d47, 0x36194d42, 0x32d850f5,
|
||||
0x3f9b762c, 0x3b5a6b9b, 0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff,
|
||||
0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623, 0xf12f560e, 0xf5ee4bb9,
|
||||
0xf8ad6d60, 0xfc6c70d7, 0xe22b20d2, 0xe6ea3d65, 0xeba91bbc, 0xef68060b,
|
||||
0xd727bbb6, 0xd3e6a601, 0xdea580d8, 0xda649d6f, 0xc423cd6a, 0xc0e2d0dd,
|
||||
0xcda1f604, 0xc960ebb3, 0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7,
|
||||
0xae3afba2, 0xaafbe615, 0xa7b8c0cc, 0xa379dd7b, 0x9b3660c6, 0x9ff77d71,
|
||||
0x92b45ba8, 0x9675461f, 0x8832161a, 0x8cf30bad, 0x81b02d74, 0x857130c3,
|
||||
0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640, 0x4e8ee645, 0x4a4ffbf2,
|
||||
0x470cdd2b, 0x43cdc09c, 0x7b827d21, 0x7f436096, 0x7200464f, 0x76c15bf8,
|
||||
0x68860bfd, 0x6c47164a, 0x61043093, 0x65c52d24, 0x119b4be9, 0x155a565e,
|
||||
0x18197087, 0x1cd86d30, 0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec,
|
||||
0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088, 0x2497d08d, 0x2056cd3a,
|
||||
0x2d15ebe3, 0x29d4f654, 0xc5a92679, 0xc1683bce, 0xcc2b1d17, 0xc8ea00a0,
|
||||
0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb, 0xdbee767c, 0xe3a1cbc1, 0xe760d676,
|
||||
0xea23f0af, 0xeee2ed18, 0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4,
|
||||
0x89b8fd09, 0x8d79e0be, 0x803ac667, 0x84fbdbd0, 0x9abc8bd5, 0x9e7d9662,
|
||||
0x933eb0bb, 0x97ffad0c, 0xafb010b1, 0xab710d06, 0xa6322bdf, 0xa2f33668,
|
||||
0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4
|
||||
};
|
||||
|
||||
// Nallocfuzz data to take a decision
|
||||
uint32_t nalloc_random_state = 0;
|
||||
__thread unsigned int nalloc_running = 0;
|
||||
bool nalloc_initialized = false;
|
||||
uint32_t nalloc_runs = 0;
|
||||
|
||||
// Nalloc fuzz parameters
|
||||
uint32_t nalloc_bitmask = 0xFF;
|
||||
bool nalloc_random_bitmask = true;
|
||||
uint32_t nalloc_magic = 0x294cee63;
|
||||
bool nalloc_verbose = false;
|
||||
|
||||
#ifdef NALLOC_ASAN
|
||||
extern void __sanitizer_print_stack_trace(void);
|
||||
#endif
|
||||
|
||||
// Generic init, using env variables to get parameters
|
||||
void nalloc_init(const char *prog) {
|
||||
if (nalloc_initialized) {
|
||||
return;
|
||||
}
|
||||
nalloc_initialized = true;
|
||||
char *bitmask = getenv("NALLOC_FREQ");
|
||||
if (bitmask) {
|
||||
int shift = atoi(bitmask);
|
||||
if (shift > 0 && shift < 31) {
|
||||
nalloc_bitmask = 1 << shift;
|
||||
nalloc_random_bitmask = false;
|
||||
} else if (shift == 0) {
|
||||
nalloc_random_bitmask = false;
|
||||
nalloc_bitmask = 0;
|
||||
}
|
||||
} else if (prog == NULL || strstr(prog, "nalloc") == NULL) {
|
||||
nalloc_random_bitmask = false;
|
||||
nalloc_bitmask = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
char *magic = getenv("NALLOC_MAGIC");
|
||||
if (magic) {
|
||||
nalloc_magic = (uint32_t)strtol(magic, NULL, 0);
|
||||
}
|
||||
|
||||
char *verbose = getenv("NALLOC_VERBOSE");
|
||||
if (verbose) {
|
||||
nalloc_verbose = true;
|
||||
}
|
||||
}
|
||||
|
||||
// add one byte to the CRC
|
||||
static inline void nalloc_random_update(uint8_t b) {
|
||||
nalloc_random_state =
|
||||
((uint32_t)((uint32_t)nalloc_random_state << 8)) ^
|
||||
nalloc_crc32_table[((nalloc_random_state >> 24) ^ b) & 0xFF];
|
||||
}
|
||||
|
||||
// Start the failure injections, using a buffer as seed
|
||||
static int nalloc_start(const uint8_t *data, size_t size) {
|
||||
if (nalloc_random_bitmask) {
|
||||
if (nalloc_random_state & 0x10) {
|
||||
nalloc_bitmask = 0xFFFFFFFF;
|
||||
} else {
|
||||
nalloc_bitmask = 1 << (5 + (nalloc_random_state & 0xF));
|
||||
}
|
||||
} else if (nalloc_bitmask == 0) {
|
||||
// nalloc disabled
|
||||
return 0;
|
||||
}
|
||||
nalloc_random_state = 0;
|
||||
for (size_t i = 0; i < size; i++) {
|
||||
nalloc_random_update(data[i]);
|
||||
}
|
||||
if (__sync_fetch_and_add(&nalloc_running, 1)) {
|
||||
__sync_fetch_and_sub(&nalloc_running, 1);
|
||||
return 0;
|
||||
}
|
||||
nalloc_runs++;
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Stop the failure injections
|
||||
static void nalloc_end() { __sync_fetch_and_sub(&nalloc_running, 1); }
|
||||
|
||||
static bool nalloc_backtrace_exclude(size_t size, const char *op) {
|
||||
if (nalloc_verbose) {
|
||||
fprintf(stderr, "failed %s(%zu) \n", op, size);
|
||||
#ifdef NALLOC_ASAN
|
||||
__sanitizer_print_stack_trace();
|
||||
#endif
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//
|
||||
static bool nalloc_fail(size_t size, const char *op) {
|
||||
// do not fail before thread init
|
||||
if (nalloc_runs == 0) {
|
||||
return false;
|
||||
}
|
||||
if (__sync_fetch_and_add(&nalloc_running, 1) != 1) {
|
||||
// do not fail allocations outside of fuzzer input
|
||||
// and do not fail inside of this function
|
||||
__sync_fetch_and_sub(&nalloc_running, 1);
|
||||
return false;
|
||||
}
|
||||
nalloc_random_update((uint8_t)size);
|
||||
if (size >= 0x100) {
|
||||
nalloc_random_update((uint8_t)(size >> 8));
|
||||
if (size >= 0x10000) {
|
||||
nalloc_random_update((uint8_t)(size >> 16));
|
||||
// bigger may already fail or oom
|
||||
}
|
||||
}
|
||||
if (((nalloc_random_state ^ nalloc_magic) & nalloc_bitmask) == 0) {
|
||||
if (nalloc_backtrace_exclude(size, op)) {
|
||||
__sync_fetch_and_sub(&nalloc_running, 1);
|
||||
return false;
|
||||
}
|
||||
__sync_fetch_and_sub(&nalloc_running, 1);
|
||||
return true;
|
||||
}
|
||||
__sync_fetch_and_sub(&nalloc_running, 1);
|
||||
return false;
|
||||
}
|
||||
|
||||
// ASAN interceptor for libc routines
|
||||
#ifdef NALLOC_ASAN
|
||||
extern void *__interceptor_malloc(size_t);
|
||||
extern void *__interceptor_calloc(size_t, size_t);
|
||||
extern void *__interceptor_realloc(void *, size_t);
|
||||
extern void *__interceptor_reallocarray(void *, size_t, size_t);
|
||||
|
||||
extern ssize_t __interceptor_read(int, void *, size_t);
|
||||
extern ssize_t __interceptor_write(int, const void *, size_t);
|
||||
extern ssize_t __interceptor_recv(int, void *, size_t, int);
|
||||
extern ssize_t __interceptor_send(int, const void *, size_t, int);
|
||||
|
||||
#define nalloc_malloc(s) __interceptor_malloc(s)
|
||||
#define nalloc_calloc(s, n) __interceptor_calloc(s, n)
|
||||
#define nalloc_realloc(p, s) __interceptor_realloc(p, s)
|
||||
#define nalloc_reallocarray(p, s, n) __interceptor_reallocarray(p, s, n)
|
||||
|
||||
#define nalloc_read(f, b, s) __interceptor_read(f, b, s)
|
||||
#define nalloc_write(f, b, s) __interceptor_write(f, b, s)
|
||||
#define nalloc_recv(f, b, s, x) __interceptor_recv(f, b, s, x)
|
||||
#define nalloc_send(f, b, s, x) __interceptor_send(f, b, s, x)
|
||||
|
||||
#else
|
||||
extern void *__libc_malloc(size_t);
|
||||
extern void *__libc_calloc(size_t, size_t);
|
||||
extern void *__libc_realloc(void *, size_t);
|
||||
extern void *__libc_reallocarray(void *, size_t, size_t);
|
||||
|
||||
extern ssize_t __read(int, void *, size_t);
|
||||
extern ssize_t __write(int, const void *, size_t);
|
||||
extern ssize_t __recv(int, void *, size_t, int);
|
||||
extern ssize_t __send(int, const void *, size_t, int);
|
||||
|
||||
#define nalloc_malloc(s) __libc_malloc(s)
|
||||
#define nalloc_calloc(s, n) __libc_calloc(s, n)
|
||||
#define nalloc_realloc(p, s) __libc_realloc(p, s)
|
||||
#define nalloc_reallocarray(p, s, n) __libc_reallocarray(p, s, n)
|
||||
|
||||
#define nalloc_read(f, b, s) __read(f, b, s)
|
||||
#define nalloc_write(f, b, s) __write(f, b, s)
|
||||
#define nalloc_recv(f, b, s, x) __recv(f, b, s, x)
|
||||
#define nalloc_send(f, b, s, x) __send(f, b, s, x)
|
||||
#endif
|
||||
|
||||
// nalloc standard function overwrites with pseudo-random failures
|
||||
ssize_t read(int fd, void *buf, size_t count) {
|
||||
if (nalloc_fail(count, "read")) {
|
||||
errno = EIO;
|
||||
return -1;
|
||||
}
|
||||
return nalloc_read(fd, buf, count);
|
||||
}
|
||||
|
||||
ssize_t write(int fd, const void *buf, size_t count) {
|
||||
if (nalloc_fail(count, "write")) {
|
||||
errno = EIO;
|
||||
return -1;
|
||||
}
|
||||
return nalloc_write(fd, buf, count);
|
||||
}
|
||||
|
||||
ssize_t recv(int fd, void *buf, size_t count, int flags) {
|
||||
if (nalloc_fail(count, "recv")) {
|
||||
errno = EIO;
|
||||
return -1;
|
||||
}
|
||||
return nalloc_recv(fd, buf, count, flags);
|
||||
}
|
||||
|
||||
ssize_t send(int fd, const void *buf, size_t count, int flags) {
|
||||
if (nalloc_fail(count, "send")) {
|
||||
errno = EIO;
|
||||
return -1;
|
||||
}
|
||||
return nalloc_send(fd, buf, count, flags);
|
||||
}
|
||||
|
||||
void *calloc(size_t nmemb, size_t size) {
|
||||
if (nalloc_fail(size, "calloc")) {
|
||||
errno = ENOMEM;
|
||||
return NULL;
|
||||
}
|
||||
return nalloc_calloc(nmemb, size);
|
||||
}
|
||||
|
||||
void *malloc(size_t size) {
|
||||
if (nalloc_fail(size, "malloc")) {
|
||||
errno = ENOMEM;
|
||||
return NULL;
|
||||
}
|
||||
return nalloc_malloc(size);
|
||||
}
|
||||
|
||||
void *realloc(void *ptr, size_t size) {
|
||||
if (nalloc_fail(size, "realloc")) {
|
||||
errno = ENOMEM;
|
||||
return NULL;
|
||||
}
|
||||
return nalloc_realloc(ptr, size);
|
||||
}
|
||||
|
||||
void *reallocarray(void *ptr, size_t nmemb, size_t size) {
|
||||
if (nalloc_fail(size, "reallocarray")) {
|
||||
errno = ENOMEM;
|
||||
return NULL;
|
||||
}
|
||||
return nalloc_reallocarray(ptr, nmemb, size);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C" {
|
||||
#endif
|
||||
|
||||
#endif // NALLOC_H_
|
||||
12
Engine/lib/lpng/contrib/pngexif/.editorconfig
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
# https://editorconfig.org
|
||||
|
||||
root = true
|
||||
|
||||
[*]
|
||||
charset = utf-8
|
||||
indent_size = 4
|
||||
indent_style = space
|
||||
insert_final_newline = true
|
||||
max_doc_length = 79
|
||||
max_line_length = 79
|
||||
trim_trailing_whitespace = true
|
||||
3
Engine/lib/lpng/contrib/pngexif/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
__pycache__
|
||||
*.py[co]
|
||||
*$py.class
|
||||
8
Engine/lib/lpng/contrib/pngexif/.pylintrc
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
[COMPATIBILITY]
|
||||
disable=consider-using-f-string
|
||||
|
||||
[COMPLEXITY]
|
||||
disable=too-many-branches,too-many-instance-attributes
|
||||
|
||||
[STYLE]
|
||||
disable=consider-using-in
|
||||
19
Engine/lib/lpng/contrib/pngexif/LICENSE_MIT.txt
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
MIT License
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
20
Engine/lib/lpng/contrib/pngexif/README.md
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
pngexifinfo
|
||||
===========
|
||||
|
||||
Show the EXIF information embedded in a PNG file.
|
||||
|
||||
|
||||
Sample usage
|
||||
------------
|
||||
|
||||
Show the EXIF info inside a PNG file:
|
||||
|
||||
pngexifinfo /path/to/file.png
|
||||
|
||||
Show the EXIF info inside a raw `.exif` file, using base 16 for the EXIF tags:
|
||||
|
||||
pngexifinfo --hex /path/to/file.exif
|
||||
|
||||
Show the help text:
|
||||
|
||||
pngexifinfo --help
|
||||
48
Engine/lib/lpng/contrib/pngexif/bytepack.py
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
"""
|
||||
Byte packing and unpacking utilities.
|
||||
|
||||
Copyright (C) 2017-2020 Cosmin Truta.
|
||||
|
||||
Use, modification and distribution are subject to the MIT License.
|
||||
Please see the accompanying file LICENSE_MIT.txt
|
||||
"""
|
||||
|
||||
from __future__ import absolute_import, division, print_function
|
||||
|
||||
import struct
|
||||
|
||||
|
||||
def unpack_uint32be(buffer, offset=0):
|
||||
"""Unpack an unsigned int from its 32-bit big-endian representation."""
|
||||
return struct.unpack(">I", buffer[offset:offset + 4])[0]
|
||||
|
||||
|
||||
def unpack_uint32le(buffer, offset=0):
|
||||
"""Unpack an unsigned int from its 32-bit little-endian representation."""
|
||||
return struct.unpack("<I", buffer[offset:offset + 4])[0]
|
||||
|
||||
|
||||
def unpack_uint16be(buffer, offset=0):
|
||||
"""Unpack an unsigned int from its 16-bit big-endian representation."""
|
||||
return struct.unpack(">H", buffer[offset:offset + 2])[0]
|
||||
|
||||
|
||||
def unpack_uint16le(buffer, offset=0):
|
||||
"""Unpack an unsigned int from its 16-bit little-endian representation."""
|
||||
return struct.unpack("<H", buffer[offset:offset + 2])[0]
|
||||
|
||||
|
||||
def unpack_uint8(buffer, offset=0):
|
||||
"""Unpack an unsigned int from its 8-bit representation."""
|
||||
return struct.unpack("B", buffer[offset:offset + 1])[0]
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
# For testing only.
|
||||
assert unpack_uint32be(b"ABCDEF", 1) == 0x42434445
|
||||
assert unpack_uint32le(b"ABCDEF", 1) == 0x45444342
|
||||
assert unpack_uint16be(b"ABCDEF", 1) == 0x4243
|
||||
assert unpack_uint16le(b"ABCDEF", 1) == 0x4342
|
||||
assert unpack_uint8(b"ABCDEF", 1) == 0x42
|
||||
306
Engine/lib/lpng/contrib/pngexif/exifinfo.py
Normal file
|
|
@ -0,0 +1,306 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
"""
|
||||
Show the EXIF information.
|
||||
|
||||
Copyright (C) 2017-2020 Cosmin Truta.
|
||||
|
||||
Use, modification and distribution are subject to the MIT License.
|
||||
Please see the accompanying file LICENSE_MIT.txt
|
||||
"""
|
||||
|
||||
from __future__ import absolute_import, division, print_function
|
||||
|
||||
import sys
|
||||
|
||||
from bytepack import (unpack_uint32be,
|
||||
unpack_uint32le,
|
||||
unpack_uint16be,
|
||||
unpack_uint16le,
|
||||
unpack_uint8)
|
||||
|
||||
|
||||
# Generously allow the TIFF file to occupy up to a quarter-gigabyte.
|
||||
# TODO: Reduce this limit to 64K and use file seeking for anything larger.
|
||||
_READ_DATA_SIZE_MAX = 256 * 1024 * 1024
|
||||
|
||||
_TIFF_TAG_TYPES = {
|
||||
1: "byte",
|
||||
2: "ascii",
|
||||
3: "short",
|
||||
4: "long",
|
||||
5: "rational",
|
||||
6: "sbyte",
|
||||
7: "undefined",
|
||||
8: "sshort",
|
||||
9: "slong",
|
||||
10: "srational",
|
||||
11: "float",
|
||||
12: "double",
|
||||
}
|
||||
|
||||
# See http://www.digitalpreservation.gov/formats/content/tiff_tags.shtml
|
||||
_TIFF_TAGS = {
|
||||
0x00fe: "Subfile Type",
|
||||
0x0100: "Width",
|
||||
0x0101: "Height",
|
||||
0x0102: "Bits per Sample",
|
||||
0x0103: "Compression",
|
||||
0x0106: "Photometric",
|
||||
0x010d: "Document Name",
|
||||
0x010e: "Image Description",
|
||||
0x010f: "Make",
|
||||
0x0110: "Model",
|
||||
0x0111: "Strip Offsets",
|
||||
0x0112: "Orientation",
|
||||
0x0115: "Samples per Pixel",
|
||||
0x0116: "Rows per Strip",
|
||||
0x0117: "Strip Byte Counts",
|
||||
0x0118: "Min Sample Value",
|
||||
0x0119: "Max Sample Value",
|
||||
0x011a: "X Resolution",
|
||||
0x011b: "Y Resolution",
|
||||
0x011c: "Planar Configuration",
|
||||
0x011d: "Page Name",
|
||||
0x011e: "X Position",
|
||||
0x011f: "Y Position",
|
||||
0x0128: "Resolution Unit",
|
||||
0x0129: "Page Number",
|
||||
0x0131: "Software",
|
||||
0x0132: "Date Time",
|
||||
0x013b: "Artist",
|
||||
0x013c: "Host Computer",
|
||||
0x013d: "Predictor",
|
||||
0x013e: "White Point",
|
||||
0x013f: "Primary Chromaticities",
|
||||
0x0140: "Color Map",
|
||||
0x0141: "Half-Tone Hints",
|
||||
0x0142: "Tile Width",
|
||||
0x0143: "Tile Length",
|
||||
0x0144: "Tile Offsets",
|
||||
0x0145: "Tile Byte Counts",
|
||||
0x0211: "YCbCr Coefficients",
|
||||
0x0212: "YCbCr Subsampling",
|
||||
0x0213: "YCbCr Positioning",
|
||||
0x0214: "Reference Black White",
|
||||
0x022f: "Strip Row Counts",
|
||||
0x02bc: "XMP",
|
||||
0x8298: "Copyright",
|
||||
0x83bb: "IPTC",
|
||||
0x8769: "EXIF IFD",
|
||||
0x8773: "ICC Profile",
|
||||
0x8825: "GPS IFD",
|
||||
0xa005: "Interoperability IFD",
|
||||
0xc4a5: "Print IM",
|
||||
|
||||
# EXIF IFD tags
|
||||
0x829a: "Exposure Time",
|
||||
0x829d: "F-Number",
|
||||
0x8822: "Exposure Program",
|
||||
0x8824: "Spectral Sensitivity",
|
||||
0x8827: "ISO Speed Ratings",
|
||||
0x8828: "OECF",
|
||||
0x9000: "EXIF Version",
|
||||
0x9003: "DateTime Original",
|
||||
0x9004: "DateTime Digitized",
|
||||
0x9101: "Components Configuration",
|
||||
0x9102: "Compressed Bits Per Pixel",
|
||||
0x9201: "Shutter Speed Value",
|
||||
0x9202: "Aperture Value",
|
||||
0x9203: "Brightness Value",
|
||||
0x9204: "Exposure Bias Value",
|
||||
0x9205: "Max Aperture Value",
|
||||
0x9206: "Subject Distance",
|
||||
0x9207: "Metering Mode",
|
||||
0x9208: "Light Source",
|
||||
0x9209: "Flash",
|
||||
0x920a: "Focal Length",
|
||||
0x9214: "Subject Area",
|
||||
0x927c: "Maker Note",
|
||||
0x9286: "User Comment",
|
||||
# ... TODO
|
||||
0xa000: "Flashpix Version",
|
||||
0xa001: "Color Space",
|
||||
0xa002: "Pixel X Dimension",
|
||||
0xa003: "Pixel Y Dimension",
|
||||
0xa004: "Related Sound File",
|
||||
# ... TODO
|
||||
|
||||
# GPS IFD tags
|
||||
# ... TODO
|
||||
}
|
||||
|
||||
_TIFF_EXIF_IFD = 0x8769
|
||||
_GPS_IFD = 0x8825
|
||||
_INTEROPERABILITY_IFD = 0xa005
|
||||
|
||||
|
||||
class ExifInfo:
|
||||
"""EXIF reader and information lister."""
|
||||
|
||||
_endian = None
|
||||
_buffer = None
|
||||
_offset = 0
|
||||
_global_ifd_offset = 0
|
||||
_exif_ifd_offset = 0
|
||||
_gps_ifd_offset = 0
|
||||
_interoperability_ifd_offset = 0
|
||||
_hex = False
|
||||
|
||||
def __init__(self, buffer, **kwargs):
|
||||
"""Initialize the EXIF data reader."""
|
||||
self._hex = kwargs.get("hex", False)
|
||||
self._verbose = kwargs.get("verbose", False)
|
||||
if not isinstance(buffer, bytes):
|
||||
raise RuntimeError("invalid EXIF data type")
|
||||
if buffer.startswith(b"MM\x00\x2a"):
|
||||
self._endian = "MM"
|
||||
elif buffer.startswith(b"II\x2a\x00"):
|
||||
self._endian = "II"
|
||||
else:
|
||||
raise RuntimeError("invalid EXIF header")
|
||||
self._buffer = buffer
|
||||
self._offset = 4
|
||||
self._global_ifd_offset = self._ui32()
|
||||
|
||||
def endian(self):
|
||||
"""Return the endianness of the EXIF data."""
|
||||
return self._endian
|
||||
|
||||
def _tags_for_ifd(self, ifd_offset):
|
||||
"""Yield the tags found at the given TIFF IFD offset."""
|
||||
if ifd_offset < 8:
|
||||
raise RuntimeError("invalid TIFF IFD offset")
|
||||
self._offset = ifd_offset
|
||||
ifd_size = self._ui16()
|
||||
for _ in range(0, ifd_size):
|
||||
tag_id = self._ui16()
|
||||
tag_type = self._ui16()
|
||||
count = self._ui32()
|
||||
value_or_offset = self._ui32()
|
||||
if self._endian == "MM":
|
||||
# FIXME:
|
||||
# value_or_offset requires a fixup under big-endian encoding.
|
||||
if tag_type == 2:
|
||||
# 2 --> "ascii"
|
||||
value_or_offset >>= 24
|
||||
elif tag_type == 3:
|
||||
# 3 --> "short"
|
||||
value_or_offset >>= 16
|
||||
else:
|
||||
# ... FIXME
|
||||
pass
|
||||
if count == 0:
|
||||
raise RuntimeError("unsupported count=0 in tag 0x%x" % tag_id)
|
||||
if tag_id == _TIFF_EXIF_IFD:
|
||||
if tag_type != 4:
|
||||
raise RuntimeError("incorrect tag type for EXIF IFD")
|
||||
self._exif_ifd_offset = value_or_offset
|
||||
elif tag_id == _GPS_IFD:
|
||||
if tag_type != 4:
|
||||
raise RuntimeError("incorrect tag type for GPS IFD")
|
||||
self._gps_ifd_offset = value_or_offset
|
||||
elif tag_id == _INTEROPERABILITY_IFD:
|
||||
if tag_type != 4:
|
||||
raise RuntimeError("incorrect tag type for Interop IFD")
|
||||
self._interoperability_ifd_offset = value_or_offset
|
||||
yield (tag_id, tag_type, count, value_or_offset)
|
||||
|
||||
def tags(self):
|
||||
"""Yield all TIFF/EXIF tags."""
|
||||
if self._verbose:
|
||||
print("TIFF IFD : 0x%08x" % self._global_ifd_offset)
|
||||
for tag in self._tags_for_ifd(self._global_ifd_offset):
|
||||
yield tag
|
||||
if self._exif_ifd_offset > 0:
|
||||
if self._verbose:
|
||||
print("EXIF IFD : 0x%08x" % self._exif_ifd_offset)
|
||||
for tag in self._tags_for_ifd(self._exif_ifd_offset):
|
||||
yield tag
|
||||
if self._gps_ifd_offset > 0:
|
||||
if self._verbose:
|
||||
print("GPS IFD : 0x%08x" % self._gps_ifd_offset)
|
||||
for tag in self._tags_for_ifd(self._gps_ifd_offset):
|
||||
yield tag
|
||||
if self._interoperability_ifd_offset > 0:
|
||||
if self._verbose:
|
||||
print("Interoperability IFD : 0x%08x" %
|
||||
self._interoperability_ifd_offset)
|
||||
for tag in self._tags_for_ifd(self._interoperability_ifd_offset):
|
||||
yield tag
|
||||
|
||||
def tagid2str(self, tag_id):
|
||||
"""Return an informative string representation of a TIFF tag id."""
|
||||
idstr = _TIFF_TAGS.get(tag_id, "[Unknown]")
|
||||
if self._hex:
|
||||
idnum = "0x%04x" % tag_id
|
||||
else:
|
||||
idnum = "%d" % tag_id
|
||||
return "%s (%s)" % (idstr, idnum)
|
||||
|
||||
@staticmethod
|
||||
def tagtype2str(tag_type):
|
||||
"""Return an informative string representation of a TIFF tag type."""
|
||||
typestr = _TIFF_TAG_TYPES.get(tag_type, "[unknown]")
|
||||
return "%d:%s" % (tag_type, typestr)
|
||||
|
||||
def tag2str(self, tag_id, tag_type, count, value_or_offset):
|
||||
"""Return an informative string representation of a TIFF tag tuple."""
|
||||
return "%s (type=%s) (count=%d) : 0x%08x" \
|
||||
% (self.tagid2str(tag_id), self.tagtype2str(tag_type), count,
|
||||
value_or_offset)
|
||||
|
||||
def _ui32(self):
|
||||
"""Decode a 32-bit unsigned int found at the current offset;
|
||||
advance the offset by 4.
|
||||
"""
|
||||
if self._offset + 4 > len(self._buffer):
|
||||
raise RuntimeError("out-of-bounds uint32 access in EXIF")
|
||||
if self._endian == "MM":
|
||||
result = unpack_uint32be(self._buffer, self._offset)
|
||||
else:
|
||||
result = unpack_uint32le(self._buffer, self._offset)
|
||||
self._offset += 4
|
||||
return result
|
||||
|
||||
def _ui16(self):
|
||||
"""Decode a 16-bit unsigned int found at the current offset;
|
||||
advance the offset by 2.
|
||||
"""
|
||||
if self._offset + 2 > len(self._buffer):
|
||||
raise RuntimeError("out-of-bounds uint16 access in EXIF")
|
||||
if self._endian == "MM":
|
||||
result = unpack_uint16be(self._buffer, self._offset)
|
||||
else:
|
||||
result = unpack_uint16le(self._buffer, self._offset)
|
||||
self._offset += 2
|
||||
return result
|
||||
|
||||
def _ui8(self):
|
||||
"""Decode an 8-bit unsigned int found at the current offset;
|
||||
advance the offset by 1.
|
||||
"""
|
||||
if self._offset + 1 > len(self._buffer):
|
||||
raise RuntimeError("out-of-bounds uint8 access in EXIF")
|
||||
result = unpack_uint8(self._buffer, self._offset)
|
||||
self._offset += 1
|
||||
return result
|
||||
|
||||
|
||||
def print_raw_exif_info(buffer, **kwargs):
|
||||
"""Print the EXIF information found in a raw byte stream."""
|
||||
lister = ExifInfo(buffer, **kwargs)
|
||||
print("EXIF (endian=%s)" % lister.endian())
|
||||
for (tag_id, tag_type, count, value_or_offset) in lister.tags():
|
||||
print(lister.tag2str(tag_id=tag_id,
|
||||
tag_type=tag_type,
|
||||
count=count,
|
||||
value_or_offset=value_or_offset))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
# For testing only.
|
||||
for arg in sys.argv[1:]:
|
||||
with open(arg, "rb") as test_stream:
|
||||
test_buffer = test_stream.read(_READ_DATA_SIZE_MAX)
|
||||
print_raw_exif_info(test_buffer, hex=True, verbose=True)
|
||||
10
Engine/lib/lpng/contrib/pngexif/pngexifinfo
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
#!/bin/sh
|
||||
set -eu
|
||||
|
||||
my_python="$(command -v python3 || command -v python)" || {
|
||||
echo >&2 "error: program not found: Python interpreter"
|
||||
exit 127
|
||||
}
|
||||
my_python_flags="-BES"
|
||||
|
||||
exec "$my_python" "$my_python_flags" "$(dirname "$0")/pngexifinfo.py" "$@"
|
||||
4
Engine/lib/lpng/contrib/pngexif/pngexifinfo.bat
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
@echo off
|
||||
@setlocal enableextensions
|
||||
|
||||
python.exe -BES %~dp0.\pngexifinfo.py %*
|
||||
178
Engine/lib/lpng/contrib/pngexif/pngexifinfo.py
Normal file
|
|
@ -0,0 +1,178 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
"""
|
||||
Show the PNG EXIF information.
|
||||
|
||||
Copyright (C) 2017-2020 Cosmin Truta.
|
||||
|
||||
Use, modification and distribution are subject to the MIT License.
|
||||
Please see the accompanying file LICENSE_MIT.txt
|
||||
"""
|
||||
|
||||
from __future__ import absolute_import, division, print_function
|
||||
|
||||
import argparse
|
||||
import io
|
||||
import re
|
||||
import sys
|
||||
import zlib
|
||||
|
||||
from bytepack import unpack_uint32be, unpack_uint8
|
||||
from exifinfo import print_raw_exif_info
|
||||
|
||||
_PNG_SIGNATURE = b"\x89PNG\x0d\x0a\x1a\x0a"
|
||||
_PNG_CHUNK_SIZE_MAX = 0x7fffffff
|
||||
_READ_DATA_SIZE_MAX = 0x3ffff
|
||||
|
||||
|
||||
def print_error(msg):
|
||||
"""Print an error message to stderr."""
|
||||
sys.stderr.write("%s: error: %s\n" % (sys.argv[0], msg))
|
||||
|
||||
|
||||
def print_debug(msg):
|
||||
"""Print a debug message to stderr."""
|
||||
sys.stderr.write("%s: debug: %s\n" % (sys.argv[0], msg))
|
||||
|
||||
|
||||
def _check_png(condition, chunk_sig=None):
|
||||
"""Check a PNG-specific assertion."""
|
||||
if condition:
|
||||
return
|
||||
if chunk_sig is None:
|
||||
raise RuntimeError("bad PNG data")
|
||||
raise RuntimeError("bad PNG data in '%s'" % chunk_sig)
|
||||
|
||||
|
||||
def _check_png_crc(data, checksum, chunk_sig):
|
||||
"""Check a CRC32 value inside a PNG stream."""
|
||||
if unpack_uint32be(data) == (checksum & 0xffffffff):
|
||||
return
|
||||
raise RuntimeError("bad PNG checksum in '%s'" % chunk_sig)
|
||||
|
||||
|
||||
def _extract_png_exif(data, **kwargs):
|
||||
"""Extract the EXIF header and data from a PNG chunk."""
|
||||
debug = kwargs.get("debug", False)
|
||||
if unpack_uint8(data, 0) == 0:
|
||||
if debug:
|
||||
print_debug("found compressed EXIF, compression method 0")
|
||||
if (unpack_uint8(data, 1) & 0x0f) == 0x08:
|
||||
data = zlib.decompress(data[1:])
|
||||
elif unpack_uint8(data, 1) == 0 \
|
||||
and (unpack_uint8(data, 5) & 0x0f) == 0x08:
|
||||
if debug:
|
||||
print_debug("found uncompressed-length EXIF field")
|
||||
data_len = unpack_uint32be(data, 1)
|
||||
data = zlib.decompress(data[5:])
|
||||
if data_len != len(data):
|
||||
raise RuntimeError(
|
||||
"incorrect uncompressed-length field in PNG EXIF")
|
||||
else:
|
||||
raise RuntimeError("invalid compression method in PNG EXIF")
|
||||
if data.startswith(b"MM\x00\x2a") or data.startswith(b"II\x2a\x00"):
|
||||
return data
|
||||
raise RuntimeError("invalid TIFF/EXIF header in PNG EXIF")
|
||||
|
||||
|
||||
def print_png_exif_info(instream, **kwargs):
|
||||
"""Print the EXIF information found in the given PNG datastream."""
|
||||
debug = kwargs.get("debug", False)
|
||||
has_exif = False
|
||||
while True:
|
||||
chunk_hdr = instream.read(8)
|
||||
_check_png(len(chunk_hdr) == 8)
|
||||
chunk_len = unpack_uint32be(chunk_hdr, offset=0)
|
||||
chunk_sig = chunk_hdr[4:8].decode("latin_1", errors="ignore")
|
||||
_check_png(re.search(r"^[A-Za-z]{4}$", chunk_sig), chunk_sig=chunk_sig)
|
||||
_check_png(chunk_len < _PNG_CHUNK_SIZE_MAX, chunk_sig=chunk_sig)
|
||||
if debug:
|
||||
print_debug("processing chunk: %s" % chunk_sig)
|
||||
if chunk_len <= _READ_DATA_SIZE_MAX:
|
||||
# The chunk size does not exceed an arbitrary, reasonable limit.
|
||||
chunk_data = instream.read(chunk_len)
|
||||
chunk_crc = instream.read(4)
|
||||
_check_png(len(chunk_data) == chunk_len and len(chunk_crc) == 4,
|
||||
chunk_sig=chunk_sig)
|
||||
checksum = zlib.crc32(chunk_hdr[4:8])
|
||||
checksum = zlib.crc32(chunk_data, checksum)
|
||||
_check_png_crc(chunk_crc, checksum, chunk_sig=chunk_sig)
|
||||
else:
|
||||
# The chunk is too big. Skip it.
|
||||
instream.seek(chunk_len + 4, io.SEEK_CUR)
|
||||
continue
|
||||
if chunk_sig == "IEND":
|
||||
_check_png(chunk_len == 0, chunk_sig=chunk_sig)
|
||||
break
|
||||
if chunk_sig.lower() in ["exif", "zxif"] and chunk_len > 8:
|
||||
has_exif = True
|
||||
exif_data = _extract_png_exif(chunk_data, **kwargs)
|
||||
print_raw_exif_info(exif_data, **kwargs)
|
||||
if not has_exif:
|
||||
raise RuntimeError("no EXIF data in PNG stream")
|
||||
|
||||
|
||||
def print_exif_info(file, **kwargs):
|
||||
"""Print the EXIF information found in the given file."""
|
||||
with open(file, "rb") as stream:
|
||||
header = stream.read(4)
|
||||
if header == _PNG_SIGNATURE[0:4]:
|
||||
if stream.read(4) != _PNG_SIGNATURE[4:8]:
|
||||
raise RuntimeError("corrupted PNG file")
|
||||
print_png_exif_info(instream=stream, **kwargs)
|
||||
elif header == b"II\x2a\x00" or header == b"MM\x00\x2a":
|
||||
data = header + stream.read(_READ_DATA_SIZE_MAX)
|
||||
print_raw_exif_info(data, **kwargs)
|
||||
else:
|
||||
raise RuntimeError("not a PNG file")
|
||||
|
||||
|
||||
def main():
|
||||
"""The main function."""
|
||||
parser = argparse.ArgumentParser(
|
||||
prog="pngexifinfo",
|
||||
usage="%(prog)s [options] [--] files...",
|
||||
description="Show the PNG EXIF information.")
|
||||
parser.add_argument("files",
|
||||
metavar="file",
|
||||
nargs="*",
|
||||
help="a PNG file or a raw EXIF blob")
|
||||
parser.add_argument("-x",
|
||||
"--hex",
|
||||
dest="hex",
|
||||
action="store_true",
|
||||
help="show EXIF tags in base 16")
|
||||
parser.add_argument("-v",
|
||||
"--verbose",
|
||||
dest="verbose",
|
||||
action="store_true",
|
||||
help="run in verbose mode")
|
||||
parser.add_argument("--debug",
|
||||
dest="debug",
|
||||
action="store_true",
|
||||
help="run in debug mode")
|
||||
args = parser.parse_args()
|
||||
if not args.files:
|
||||
parser.error("missing file operand")
|
||||
result = 0
|
||||
for file in args.files:
|
||||
try:
|
||||
print_exif_info(file,
|
||||
hex=args.hex,
|
||||
debug=args.debug,
|
||||
verbose=args.verbose)
|
||||
except (IOError, OSError) as err:
|
||||
print_error(str(err))
|
||||
result = 66 # os.EX_NOINPUT
|
||||
except RuntimeError as err:
|
||||
print_error("%s: %s" % (file, str(err)))
|
||||
result = 69 # os.EX_UNAVAILABLE
|
||||
parser.exit(result)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
try:
|
||||
main()
|
||||
except KeyboardInterrupt:
|
||||
sys.stderr.write("INTERRUPTED\n")
|
||||
sys.exit(130) # SIGINT
|
||||
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
This demonstrates the use of PNG_USER_CONFIG, pngusr.h and pngusr.dfa
|
||||
to build minimal decoder, encoder, and progressive reader applications.
|
||||
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ ZOBJS = adler32$(O) crc32$(O) \
|
|||
PNGSRCS=png$(C) pngerror$(C) pngget$(C) pngmem$(C) \
|
||||
pngread$(C) pngrio$(C) pngrtran$(C) pngrutil$(C) \
|
||||
pngset$(C) pngtrans$(C)
|
||||
|
||||
|
||||
# Standard headers
|
||||
PNGH =png.h pngconf.h pngdebug.h pnginfo.h pngpriv.h pngstruct.h
|
||||
|
||||
|
|
|
|||
29
Engine/lib/lpng/contrib/pngminus/.editorconfig
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
# https://editorconfig.org
|
||||
|
||||
root = true
|
||||
|
||||
[*]
|
||||
charset = utf-8
|
||||
end_of_line = unset
|
||||
indent_size = unset
|
||||
indent_style = space
|
||||
insert_final_newline = true
|
||||
max_doc_length = 79
|
||||
max_line_length = 79
|
||||
trim_trailing_whitespace = true
|
||||
|
||||
[*.[ch]]
|
||||
indent_size = 2
|
||||
indent_style = space
|
||||
|
||||
[CMakeLists.txt]
|
||||
indent_size = 4
|
||||
indent_style = space
|
||||
max_doc_length = 79
|
||||
max_line_length = 99
|
||||
|
||||
[{Makefile,makevms.com}]
|
||||
indent_size = unset
|
||||
indent_style = unset
|
||||
max_doc_length = 79
|
||||
max_line_length = 99
|
||||
11
Engine/lib/lpng/contrib/pngminus/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
# Compiled executables
|
||||
png2pnm
|
||||
png2pnm.exe
|
||||
png2pnm-static*
|
||||
pnm2png
|
||||
pnm2png.exe
|
||||
pnm2png-static*
|
||||
|
||||
# Test artifacts
|
||||
*.png
|
||||
*.p[abgnp]m
|
||||
|
|
@ -1,9 +1,8 @@
|
|||
|
||||
pnm2png / png2pnm --- conversion from PBM/PGM/PPM-file to PNG-file
|
||||
copyright (C) 1999-2019 by Willem van Schaik <willem at schaik dot com>
|
||||
|
||||
version 1.0 - 1999.10.15 - First version.
|
||||
1.1 - 2015.07.29 - Fixed leaks (Glenn Randers-Pehrson)
|
||||
1.1 - 2015.07.29 - Fix memory leaks (Glenn Randers-Pehrson)
|
||||
1.2 - 2017.04.22 - Add buffer-size check
|
||||
1.3 - 2017.08.24 - Fix potential overflow in buffer-size check
|
||||
(Glenn Randers-Pehrson)
|
||||
|
|
@ -11,3 +10,5 @@ version 1.0 - 1999.10.15 - First version.
|
|||
1.5 - 2018.08.05 - Fix buffer overflow in tokenizer (Cosmin Truta)
|
||||
1.6 - 2018.08.05 - Improve portability and fix style (Cosmin Truta)
|
||||
1.7 - 2019.01.22 - Change license to MIT (Willem van Schaik)
|
||||
1.8 - 2024.01.09 - Fix, improve, modernize (Cosmin Truta)
|
||||
1.9 - 2025.01.10 - Delete conditionally-compiled code (Cosmin Truta)
|
||||
|
|
|
|||
|
|
@ -1,24 +1,41 @@
|
|||
cmake_minimum_required(VERSION 3.1)
|
||||
cmake_policy(VERSION 3.1)
|
||||
# Copyright (c) 2018-2025 Cosmin Truta
|
||||
#
|
||||
# This software is released under the MIT license. For conditions of
|
||||
# distribution and use, see the LICENSE file part of this package.
|
||||
|
||||
cmake_minimum_required(VERSION 3.14)
|
||||
|
||||
project(PNGMINUS C)
|
||||
|
||||
option(PNGMINUS_USE_STATIC_LIBRARIES "Use the static library builds" ON)
|
||||
option(PNGMINUS_USE_SYSTEM_PNG
|
||||
"Use the libpng build found in the system" OFF)
|
||||
|
||||
# libpng
|
||||
add_subdirectory(../.. libpng)
|
||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../..)
|
||||
include_directories(${CMAKE_CURRENT_BINARY_DIR}/libpng)
|
||||
if(PNGMINUS_USE_STATIC_LIBRARIES)
|
||||
set(PNGMINUS_PNG_LIBRARY png_static)
|
||||
else()
|
||||
set(PNGMINUS_PNG_LIBRARY png)
|
||||
endif()
|
||||
|
||||
# png2pnm
|
||||
add_executable(png2pnm png2pnm.c)
|
||||
target_link_libraries(png2pnm ${PNGMINUS_PNG_LIBRARY})
|
||||
|
||||
# pnm2png
|
||||
add_executable(pnm2png pnm2png.c)
|
||||
target_link_libraries(pnm2png ${PNGMINUS_PNG_LIBRARY})
|
||||
|
||||
if(PNGMINUS_USE_SYSTEM_PNG)
|
||||
# Use the system libpng.
|
||||
find_package(PNG REQUIRED)
|
||||
target_link_libraries(png2pnm PRIVATE PNG::PNG)
|
||||
target_link_libraries(pnm2png PRIVATE PNG::PNG)
|
||||
else()
|
||||
# Build and use the internal libpng.
|
||||
# Configure libpng for static linking, to produce single-file executables.
|
||||
set(PNG_STATIC ON
|
||||
CACHE STRING "Build the internal libpng as a static library" FORCE)
|
||||
set(PNG_SHARED OFF
|
||||
CACHE STRING "Build the internal libpng as a shared library" FORCE)
|
||||
set(PNG_FRAMEWORK OFF
|
||||
CACHE STRING "Build the internal libpng as a framework bundle" FORCE)
|
||||
add_subdirectory(../.. libpng)
|
||||
target_include_directories(png2pnm PRIVATE
|
||||
"$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/../..>"
|
||||
"$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/libpng>"
|
||||
)
|
||||
target_include_directories(pnm2png PRIVATE
|
||||
"$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/../..>"
|
||||
"$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/libpng>"
|
||||
)
|
||||
target_link_libraries(png2pnm PRIVATE png_static)
|
||||
target_link_libraries(pnm2png PRIVATE png_static)
|
||||
endif()
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
pnm2png / png2pnm --- conversion from PBM/PGM/PPM-file to PNG-file
|
||||
|
||||
copyright (C) 1999-2019 by Willem van Schaik <willem at schaik dot com>
|
||||
|
|
@ -16,7 +15,7 @@ copies or substantial portions of the Software.
|
|||
The software is provided "as is", without warranty of any kind, express or
|
||||
implied, including but not limited to the warranties of merchantability,
|
||||
fitness for a particular purpose and noninfringement. In no event shall the
|
||||
authors or copyight holders be liable for any claim, damages or other
|
||||
authors or copyright holders be liable for any claim, damages or other
|
||||
liability, whether in an action of contract, tort or otherwise, arising from,
|
||||
out of or in connection with the software or the use or other dealings in the
|
||||
software.
|
||||
|
|
|
|||
|
|
@ -14,15 +14,10 @@
|
|||
#define BOOL unsigned char
|
||||
#endif
|
||||
#ifndef TRUE
|
||||
#define TRUE (BOOL) 1
|
||||
#define TRUE ((BOOL) 1)
|
||||
#endif
|
||||
#ifndef FALSE
|
||||
#define FALSE (BOOL) 0
|
||||
#endif
|
||||
|
||||
/* make png2pnm verbose so we can find problems (needs to be before png.h) */
|
||||
#ifndef PNG_DEBUG
|
||||
#define PNG_DEBUG 0
|
||||
#define FALSE ((BOOL) 0)
|
||||
#endif
|
||||
|
||||
#include "png.h"
|
||||
|
|
@ -33,6 +28,9 @@ int main (int argc, char *argv[]);
|
|||
void usage ();
|
||||
BOOL png2pnm (FILE *png_file, FILE *pnm_file, FILE *alpha_file,
|
||||
BOOL raw, BOOL alpha);
|
||||
BOOL do_png2pnm (png_struct *png_ptr, png_info *info_ptr,
|
||||
FILE *pnm_file, FILE *alpha_file,
|
||||
BOOL raw, BOOL alpha);
|
||||
|
||||
/*
|
||||
* main
|
||||
|
|
@ -43,9 +41,12 @@ int main (int argc, char *argv[])
|
|||
FILE *fp_rd = stdin;
|
||||
FILE *fp_wr = stdout;
|
||||
FILE *fp_al = NULL;
|
||||
const char *fname_wr = NULL;
|
||||
const char *fname_al = NULL;
|
||||
BOOL raw = TRUE;
|
||||
BOOL alpha = FALSE;
|
||||
int argi;
|
||||
int ret;
|
||||
|
||||
for (argi = 1; argi < argc; argi++)
|
||||
{
|
||||
|
|
@ -64,7 +65,8 @@ int main (int argc, char *argv[])
|
|||
argi++;
|
||||
if ((fp_al = fopen (argv[argi], "wb")) == NULL)
|
||||
{
|
||||
fprintf (stderr, "PNM2PNG\n");
|
||||
fname_al = argv[argi];
|
||||
fprintf (stderr, "PNG2PNM\n");
|
||||
fprintf (stderr, "Error: cannot create alpha-channel file %s\n",
|
||||
argv[argi]);
|
||||
exit (1);
|
||||
|
|
@ -94,6 +96,7 @@ int main (int argc, char *argv[])
|
|||
}
|
||||
else if (fp_wr == stdout)
|
||||
{
|
||||
fname_wr = argv[argi];
|
||||
if ((fp_wr = fopen (argv[argi], "wb")) == NULL)
|
||||
{
|
||||
fprintf (stderr, "PNG2PNM\n");
|
||||
|
|
@ -119,12 +122,7 @@ int main (int argc, char *argv[])
|
|||
#endif
|
||||
|
||||
/* call the conversion program itself */
|
||||
if (png2pnm (fp_rd, fp_wr, fp_al, raw, alpha) == FALSE)
|
||||
{
|
||||
fprintf (stderr, "PNG2PNM\n");
|
||||
fprintf (stderr, "Error: unsuccessful conversion of PNG-image\n");
|
||||
exit (1);
|
||||
}
|
||||
ret = png2pnm (fp_rd, fp_wr, fp_al, raw, alpha);
|
||||
|
||||
/* close input file */
|
||||
fclose (fp_rd);
|
||||
|
|
@ -134,6 +132,17 @@ int main (int argc, char *argv[])
|
|||
if (alpha)
|
||||
fclose (fp_al);
|
||||
|
||||
if (!ret)
|
||||
{
|
||||
fprintf (stderr, "PNG2PNM\n");
|
||||
fprintf (stderr, "Error: unsuccessful conversion of PNG-image\n");
|
||||
if (fname_wr)
|
||||
remove (fname_wr); /* no broken output file shall remain behind */
|
||||
if (fname_al)
|
||||
remove (fname_al); /* ditto */
|
||||
exit (1);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -163,35 +172,11 @@ void usage ()
|
|||
BOOL png2pnm (FILE *png_file, FILE *pnm_file, FILE *alpha_file,
|
||||
BOOL raw, BOOL alpha)
|
||||
{
|
||||
png_struct *png_ptr = NULL;
|
||||
png_info *info_ptr = NULL;
|
||||
png_byte buf[8];
|
||||
png_byte *png_pixels = NULL;
|
||||
png_byte **row_pointers = NULL;
|
||||
png_byte *pix_ptr = NULL;
|
||||
png_uint_32 row_bytes;
|
||||
png_struct *png_ptr;
|
||||
png_info *info_ptr;
|
||||
BOOL ret;
|
||||
|
||||
png_uint_32 width;
|
||||
png_uint_32 height;
|
||||
int bit_depth;
|
||||
int channels;
|
||||
int color_type;
|
||||
int alpha_present;
|
||||
int row, col;
|
||||
int ret;
|
||||
int i;
|
||||
long dep_16;
|
||||
|
||||
/* read and check signature in PNG file */
|
||||
ret = fread (buf, 1, 8, png_file);
|
||||
if (ret != 8)
|
||||
return FALSE;
|
||||
|
||||
ret = png_sig_cmp (buf, 0, 8);
|
||||
if (ret != 0)
|
||||
return FALSE;
|
||||
|
||||
/* create png and info structures */
|
||||
/* initialize the libpng context for reading from png_file */
|
||||
|
||||
png_ptr = png_create_read_struct (png_get_libpng_ver(NULL),
|
||||
NULL, NULL, NULL);
|
||||
|
|
@ -208,64 +193,56 @@ BOOL png2pnm (FILE *png_file, FILE *pnm_file, FILE *alpha_file,
|
|||
if (setjmp (png_jmpbuf (png_ptr)))
|
||||
{
|
||||
png_destroy_read_struct (&png_ptr, &info_ptr, NULL);
|
||||
return FALSE;
|
||||
return FALSE; /* generic libpng error */
|
||||
}
|
||||
|
||||
/* set up the input control for C streams */
|
||||
png_init_io (png_ptr, png_file);
|
||||
png_set_sig_bytes (png_ptr, 8); /* we already read the 8 signature bytes */
|
||||
|
||||
/* read the file information */
|
||||
png_read_info (png_ptr, info_ptr);
|
||||
/* do the actual conversion */
|
||||
ret = do_png2pnm (png_ptr, info_ptr, pnm_file, alpha_file, raw, alpha);
|
||||
|
||||
/* get size and bit-depth of the PNG-image */
|
||||
/* clean up the libpng structures and their internally-managed data */
|
||||
png_destroy_read_struct (&png_ptr, &info_ptr, NULL);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* do_png2pnm - does the conversion in a fully-initialized libpng context
|
||||
*/
|
||||
|
||||
BOOL do_png2pnm (png_struct *png_ptr, png_info *info_ptr,
|
||||
FILE *pnm_file, FILE *alpha_file,
|
||||
BOOL raw, BOOL alpha)
|
||||
{
|
||||
png_byte **row_pointers;
|
||||
png_byte *pix_ptr;
|
||||
png_uint_32 width;
|
||||
png_uint_32 height;
|
||||
int bit_depth;
|
||||
int channels;
|
||||
int color_type;
|
||||
int alpha_present;
|
||||
png_uint_32 row, col, i;
|
||||
long dep_16;
|
||||
|
||||
/* set up the image transformations that are necessary for the PNM format */
|
||||
|
||||
/* set up (if applicable) the expansion of paletted images to full-color rgb,
|
||||
* and the expansion of transparency maps to full alpha-channel */
|
||||
png_set_expand (png_ptr);
|
||||
|
||||
/* set up (if applicable) the expansion of grayscale images to bit-depth 8 */
|
||||
png_set_expand_gray_1_2_4_to_8 (png_ptr);
|
||||
|
||||
/* read the image file, with all of the above image transforms applied */
|
||||
png_read_png (png_ptr, info_ptr, 0, NULL);
|
||||
|
||||
/* get the image size, bit-depth and color-type */
|
||||
png_get_IHDR (png_ptr, info_ptr, &width, &height, &bit_depth, &color_type,
|
||||
NULL, NULL, NULL);
|
||||
|
||||
/* set-up the transformations */
|
||||
|
||||
/* transform paletted images into full-color rgb */
|
||||
if (color_type == PNG_COLOR_TYPE_PALETTE)
|
||||
png_set_expand (png_ptr);
|
||||
/* expand images to bit-depth 8 (only applicable for grayscale images) */
|
||||
if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8)
|
||||
png_set_expand (png_ptr);
|
||||
/* transform transparency maps into full alpha-channel */
|
||||
if (png_get_valid (png_ptr, info_ptr, PNG_INFO_tRNS))
|
||||
png_set_expand (png_ptr);
|
||||
|
||||
#ifdef NJET
|
||||
/* downgrade 16-bit images to 8-bit */
|
||||
if (bit_depth == 16)
|
||||
png_set_strip_16 (png_ptr);
|
||||
/* transform grayscale images into full-color */
|
||||
if (color_type == PNG_COLOR_TYPE_GRAY ||
|
||||
color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
|
||||
png_set_gray_to_rgb (png_ptr);
|
||||
/* only if file has a file gamma, we do a correction */
|
||||
if (png_get_gAMA (png_ptr, info_ptr, &file_gamma))
|
||||
png_set_gamma (png_ptr, (double) 2.2, file_gamma);
|
||||
#endif
|
||||
|
||||
/* all transformations have been registered; now update info_ptr data,
|
||||
* get rowbytes and channels, and allocate image memory */
|
||||
|
||||
png_read_update_info (png_ptr, info_ptr);
|
||||
|
||||
/* get the new color-type and bit-depth (after expansion/stripping) */
|
||||
png_get_IHDR (png_ptr, info_ptr, &width, &height, &bit_depth, &color_type,
|
||||
NULL, NULL, NULL);
|
||||
|
||||
/* check for 16-bit files */
|
||||
if (bit_depth == 16)
|
||||
{
|
||||
raw = FALSE;
|
||||
#if defined(O_BINARY) && (O_BINARY != 0)
|
||||
setmode (fileno (pnm_file), O_BINARY);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* calculate new number of channels and store alpha-presence */
|
||||
/* calculate the number of channels and store alpha-presence */
|
||||
if (color_type == PNG_COLOR_TYPE_GRAY)
|
||||
channels = 1;
|
||||
else if (color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
|
||||
|
|
@ -282,47 +259,12 @@ BOOL png2pnm (FILE *png_file, FILE *pnm_file, FILE *alpha_file,
|
|||
if (alpha && !alpha_present)
|
||||
{
|
||||
fprintf (stderr, "PNG2PNM\n");
|
||||
fprintf (stderr, "Error: PNG-file doesn't contain alpha channel\n");
|
||||
exit (1);
|
||||
}
|
||||
|
||||
/* row_bytes is the width x number of channels x (bit-depth / 8) */
|
||||
row_bytes = png_get_rowbytes (png_ptr, info_ptr);
|
||||
|
||||
if ((row_bytes == 0) ||
|
||||
((size_t) height > (size_t) (-1) / (size_t) row_bytes))
|
||||
{
|
||||
/* too big */
|
||||
png_destroy_read_struct (&png_ptr, &info_ptr, NULL);
|
||||
return FALSE;
|
||||
}
|
||||
if ((png_pixels = (png_byte *)
|
||||
malloc ((size_t) row_bytes * (size_t) height)) == NULL)
|
||||
{
|
||||
png_destroy_read_struct (&png_ptr, &info_ptr, NULL);
|
||||
fprintf (stderr, "Warning: no alpha channel in PNG file\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if ((row_pointers = (png_byte **)
|
||||
malloc ((size_t) height * sizeof (png_byte *))) == NULL)
|
||||
{
|
||||
png_destroy_read_struct (&png_ptr, &info_ptr, NULL);
|
||||
free (png_pixels);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* set the individual row_pointers to point at the correct offsets */
|
||||
for (i = 0; i < ((int) height); i++)
|
||||
row_pointers[i] = png_pixels + i * row_bytes;
|
||||
|
||||
/* now we can go ahead and just read the whole image */
|
||||
png_read_image (png_ptr, row_pointers);
|
||||
|
||||
/* read rest of file, and get additional chunks in info_ptr - REQUIRED */
|
||||
png_read_end (png_ptr, info_ptr);
|
||||
|
||||
/* clean up after the read, and free any memory allocated - REQUIRED */
|
||||
png_destroy_read_struct (&png_ptr, &info_ptr, NULL);
|
||||
/* get address of internally-allocated image data */
|
||||
row_pointers = png_get_rows (png_ptr, info_ptr);
|
||||
|
||||
/* write header of PNM file */
|
||||
|
||||
|
|
@ -353,24 +295,27 @@ BOOL png2pnm (FILE *png_file, FILE *pnm_file, FILE *alpha_file,
|
|||
}
|
||||
|
||||
/* write data to PNM file */
|
||||
pix_ptr = png_pixels;
|
||||
|
||||
for (row = 0; row < (int) height; row++)
|
||||
for (row = 0; row < height; row++)
|
||||
{
|
||||
for (col = 0; col < (int) width; col++)
|
||||
pix_ptr = row_pointers[row];
|
||||
for (col = 0; col < width; col++)
|
||||
{
|
||||
for (i = 0; i < (channels - alpha_present); i++)
|
||||
for (i = 0; i < (png_uint_32) (channels - alpha_present); i++)
|
||||
{
|
||||
if (raw)
|
||||
{
|
||||
fputc ((int) *pix_ptr++, pnm_file);
|
||||
if (bit_depth == 16)
|
||||
fputc ((int) *pix_ptr++, pnm_file);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (bit_depth == 16)
|
||||
{
|
||||
dep_16 = (long) *pix_ptr++;
|
||||
fprintf (pnm_file, "%ld ", (dep_16 << 8) + ((long) *pix_ptr++));
|
||||
dep_16 = ((long) *pix_ptr++) << 8;
|
||||
dep_16 += ((long) *pix_ptr++);
|
||||
fprintf (pnm_file, "%ld ", dep_16);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -382,22 +327,27 @@ BOOL png2pnm (FILE *png_file, FILE *pnm_file, FILE *alpha_file,
|
|||
{
|
||||
if (!alpha)
|
||||
{
|
||||
pix_ptr++; /* alpha */
|
||||
/* skip the alpha-channel */
|
||||
pix_ptr++;
|
||||
if (bit_depth == 16)
|
||||
pix_ptr++;
|
||||
}
|
||||
else /* output alpha-channel as pgm file */
|
||||
else
|
||||
{
|
||||
/* output the alpha-channel as pgm file */
|
||||
if (raw)
|
||||
{
|
||||
fputc ((int) *pix_ptr++, alpha_file);
|
||||
if (bit_depth == 16)
|
||||
fputc ((int) *pix_ptr++, alpha_file);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (bit_depth == 16)
|
||||
{
|
||||
dep_16 = (long) *pix_ptr++;
|
||||
fprintf (alpha_file, "%ld ", (dep_16 << 8) + (long) *pix_ptr++);
|
||||
dep_16 = ((long) *pix_ptr++) << 8;
|
||||
dep_16 += ((long) *pix_ptr++);
|
||||
fprintf (alpha_file, "%ld ", dep_16);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -417,11 +367,5 @@ BOOL png2pnm (FILE *png_file, FILE *pnm_file, FILE *alpha_file,
|
|||
fprintf (pnm_file, "\n");
|
||||
} /* end for row */
|
||||
|
||||
if (row_pointers != NULL)
|
||||
free (row_pointers);
|
||||
if (png_pixels != NULL)
|
||||
free (png_pixels);
|
||||
|
||||
return TRUE;
|
||||
|
||||
} /* end of source */
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@
|
|||
* distribution and use, see the LICENSE file part of this package.
|
||||
*/
|
||||
|
||||
#include <limits.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <fcntl.h>
|
||||
|
|
@ -14,15 +15,10 @@
|
|||
#define BOOL unsigned char
|
||||
#endif
|
||||
#ifndef TRUE
|
||||
#define TRUE (BOOL) 1
|
||||
#define TRUE ((BOOL) 1)
|
||||
#endif
|
||||
#ifndef FALSE
|
||||
#define FALSE (BOOL) 0
|
||||
#endif
|
||||
|
||||
/* make pnm2png verbose so we can find problems (needs to be before png.h) */
|
||||
#ifndef PNG_DEBUG
|
||||
#define PNG_DEBUG 0
|
||||
#define FALSE ((BOOL) 0)
|
||||
#endif
|
||||
|
||||
#include "png.h"
|
||||
|
|
@ -33,9 +29,14 @@ int main (int argc, char *argv[]);
|
|||
void usage ();
|
||||
BOOL pnm2png (FILE *pnm_file, FILE *png_file, FILE *alpha_file,
|
||||
BOOL interlace, BOOL alpha);
|
||||
void get_token (FILE *pnm_file, char *token_buf, size_t token_buf_size);
|
||||
png_uint_32 get_data (FILE *pnm_file, int depth);
|
||||
png_uint_32 get_value (FILE *pnm_file, int depth);
|
||||
BOOL do_pnm2png (png_struct *png_ptr, png_info *info_ptr,
|
||||
FILE *pnm_file, FILE *alpha_file,
|
||||
BOOL interlace, BOOL alpha);
|
||||
int fscan_pnm_magic (FILE *pnm_file, char *magic_buf, size_t magic_buf_size);
|
||||
int fscan_pnm_token (FILE *pnm_file, char *token_buf, size_t token_buf_size);
|
||||
int fscan_pnm_uint_32 (FILE *pnm_file, png_uint_32 *num_ptr);
|
||||
png_uint_32 get_pnm_data (FILE *pnm_file, int depth);
|
||||
png_uint_32 get_pnm_value (FILE *pnm_file, int depth);
|
||||
|
||||
/*
|
||||
* main
|
||||
|
|
@ -46,9 +47,11 @@ int main (int argc, char *argv[])
|
|||
FILE *fp_rd = stdin;
|
||||
FILE *fp_al = NULL;
|
||||
FILE *fp_wr = stdout;
|
||||
const char *fname_wr = NULL;
|
||||
BOOL interlace = FALSE;
|
||||
BOOL alpha = FALSE;
|
||||
int argi;
|
||||
int ret;
|
||||
|
||||
for (argi = 1; argi < argc; argi++)
|
||||
{
|
||||
|
|
@ -94,6 +97,7 @@ int main (int argc, char *argv[])
|
|||
}
|
||||
else if (fp_wr == stdout)
|
||||
{
|
||||
fname_wr = argv[argi];
|
||||
if ((fp_wr = fopen (argv[argi], "wb")) == NULL)
|
||||
{
|
||||
fprintf (stderr, "PNM2PNG\n");
|
||||
|
|
@ -121,12 +125,7 @@ int main (int argc, char *argv[])
|
|||
#endif
|
||||
|
||||
/* call the conversion program itself */
|
||||
if (pnm2png (fp_rd, fp_wr, fp_al, interlace, alpha) == FALSE)
|
||||
{
|
||||
fprintf (stderr, "PNM2PNG\n");
|
||||
fprintf (stderr, "Error: unsuccessful converting to PNG-image\n");
|
||||
exit (1);
|
||||
}
|
||||
ret = pnm2png (fp_rd, fp_wr, fp_al, interlace, alpha);
|
||||
|
||||
/* close input file */
|
||||
fclose (fp_rd);
|
||||
|
|
@ -136,6 +135,15 @@ int main (int argc, char *argv[])
|
|||
if (alpha)
|
||||
fclose (fp_al);
|
||||
|
||||
if (!ret)
|
||||
{
|
||||
fprintf (stderr, "PNM2PNG\n");
|
||||
fprintf (stderr, "Error: unsuccessful converting to PNG-image\n");
|
||||
if (fname_wr)
|
||||
remove (fname_wr); /* no broken output file shall remain behind */
|
||||
exit (1);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -163,77 +171,98 @@ void usage ()
|
|||
BOOL pnm2png (FILE *pnm_file, FILE *png_file, FILE *alpha_file,
|
||||
BOOL interlace, BOOL alpha)
|
||||
{
|
||||
png_struct *png_ptr = NULL;
|
||||
png_info *info_ptr = NULL;
|
||||
png_byte *png_pixels = NULL;
|
||||
png_byte **row_pointers = NULL;
|
||||
png_byte *pix_ptr = NULL;
|
||||
volatile png_uint_32 row_bytes;
|
||||
png_struct *png_ptr;
|
||||
png_info *info_ptr;
|
||||
BOOL ret;
|
||||
|
||||
char type_token[16];
|
||||
char width_token[16];
|
||||
char height_token[16];
|
||||
char maxval_token[16];
|
||||
volatile int color_type = 1;
|
||||
unsigned long ul_width = 0, ul_alpha_width = 0;
|
||||
unsigned long ul_height = 0, ul_alpha_height = 0;
|
||||
unsigned long ul_maxval = 0;
|
||||
volatile png_uint_32 width = 0, height = 0;
|
||||
volatile png_uint_32 alpha_width = 0, alpha_height = 0;
|
||||
png_uint_32 maxval;
|
||||
volatile int bit_depth = 0;
|
||||
int channels = 0;
|
||||
int alpha_depth = 0;
|
||||
int alpha_present = 0;
|
||||
int row, col;
|
||||
BOOL raw, alpha_raw = FALSE;
|
||||
#if defined(PNG_WRITE_INVERT_SUPPORTED) || defined(PNG_WRITE_PACK_SUPPORTED)
|
||||
/* initialize the libpng context for writing to png_file */
|
||||
|
||||
png_ptr = png_create_write_struct (png_get_libpng_ver(NULL),
|
||||
NULL, NULL, NULL);
|
||||
if (!png_ptr)
|
||||
return FALSE; /* out of memory */
|
||||
|
||||
info_ptr = png_create_info_struct (png_ptr);
|
||||
if (!info_ptr)
|
||||
{
|
||||
png_destroy_write_struct (&png_ptr, NULL);
|
||||
return FALSE; /* out of memory */
|
||||
}
|
||||
|
||||
if (setjmp (png_jmpbuf (png_ptr)))
|
||||
{
|
||||
png_destroy_write_struct (&png_ptr, &info_ptr);
|
||||
return FALSE; /* generic libpng error */
|
||||
}
|
||||
|
||||
png_init_io (png_ptr, png_file);
|
||||
|
||||
/* do the actual conversion */
|
||||
ret = do_pnm2png (png_ptr, info_ptr, pnm_file, alpha_file, interlace, alpha);
|
||||
|
||||
/* clean up the libpng structures and their internally-managed data */
|
||||
png_destroy_write_struct (&png_ptr, &info_ptr);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* do_pnm2png - does the conversion in a fully-initialized libpng context
|
||||
*/
|
||||
|
||||
BOOL do_pnm2png (png_struct *png_ptr, png_info *info_ptr,
|
||||
FILE *pnm_file, FILE *alpha_file,
|
||||
BOOL interlace, BOOL alpha)
|
||||
{
|
||||
png_byte **row_pointers;
|
||||
png_byte *pix_ptr;
|
||||
int bit_depth;
|
||||
int color_type;
|
||||
int channels;
|
||||
char magic_token[4];
|
||||
BOOL raw;
|
||||
png_uint_32 width, height, maxval;
|
||||
png_uint_32 row_bytes;
|
||||
png_uint_32 row, col;
|
||||
png_uint_32 val16, i;
|
||||
png_uint_32 alpha_width = 0, alpha_height = 0;
|
||||
int alpha_depth = 0, alpha_present = 0;
|
||||
BOOL alpha_raw = FALSE;
|
||||
BOOL packed_bitmap = FALSE;
|
||||
#endif
|
||||
png_uint_32 tmp16;
|
||||
int i;
|
||||
|
||||
/* read header of PNM file */
|
||||
|
||||
get_token (pnm_file, type_token, sizeof (type_token));
|
||||
if (type_token[0] != 'P')
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
else if ((type_token[1] == '1') || (type_token[1] == '4'))
|
||||
{
|
||||
#if defined(PNG_WRITE_INVERT_SUPPORTED) || defined(PNG_WRITE_PACK_SUPPORTED)
|
||||
raw = (type_token[1] == '4');
|
||||
color_type = PNG_COLOR_TYPE_GRAY;
|
||||
get_token (pnm_file, width_token, sizeof (width_token));
|
||||
sscanf (width_token, "%lu", &ul_width);
|
||||
width = (png_uint_32) ul_width;
|
||||
get_token (pnm_file, height_token, sizeof (height_token));
|
||||
sscanf (height_token, "%lu", &ul_height);
|
||||
height = (png_uint_32) ul_height;
|
||||
bit_depth = 1;
|
||||
packed_bitmap = TRUE;
|
||||
#else
|
||||
fprintf (stderr, "PNM2PNG built without PNG_WRITE_INVERT_SUPPORTED and\n");
|
||||
fprintf (stderr, "PNG_WRITE_PACK_SUPPORTED can't read PBM (P1,P4) files\n");
|
||||
return FALSE;
|
||||
#endif
|
||||
}
|
||||
else if ((type_token[1] == '2') || (type_token[1] == '5'))
|
||||
{
|
||||
raw = (type_token[1] == '5');
|
||||
color_type = PNG_COLOR_TYPE_GRAY;
|
||||
get_token (pnm_file, width_token, sizeof (width_token));
|
||||
sscanf (width_token, "%lu", &ul_width);
|
||||
width = (png_uint_32) ul_width;
|
||||
get_token (pnm_file, height_token, sizeof (height_token));
|
||||
sscanf (height_token, "%lu", &ul_height);
|
||||
height = (png_uint_32) ul_height;
|
||||
get_token (pnm_file, maxval_token, sizeof (maxval_token));
|
||||
sscanf (maxval_token, "%lu", &ul_maxval);
|
||||
maxval = (png_uint_32) ul_maxval;
|
||||
if (fscan_pnm_magic (pnm_file, magic_token, sizeof (magic_token)) != 1)
|
||||
return FALSE; /* not a PNM file */
|
||||
|
||||
if (maxval <= 1)
|
||||
if ((magic_token[1] == '1') || (magic_token[1] == '4'))
|
||||
{
|
||||
if ((fscan_pnm_uint_32 (pnm_file, &width) != 1) ||
|
||||
(fscan_pnm_uint_32 (pnm_file, &height) != 1))
|
||||
return FALSE; /* bad PBM file header */
|
||||
} else if ((magic_token[1] == '2') || (magic_token[1] == '5') ||
|
||||
(magic_token[1] == '3') || (magic_token[1] == '6'))
|
||||
{
|
||||
if ((fscan_pnm_uint_32 (pnm_file, &width) != 1) ||
|
||||
(fscan_pnm_uint_32 (pnm_file, &height) != 1) ||
|
||||
(fscan_pnm_uint_32 (pnm_file, &maxval) != 1))
|
||||
return FALSE; /* bad PGM/PPM file header */
|
||||
}
|
||||
|
||||
if ((magic_token[1] == '1') || (magic_token[1] == '4'))
|
||||
{
|
||||
raw = (magic_token[1] == '4');
|
||||
bit_depth = 1;
|
||||
color_type = PNG_COLOR_TYPE_GRAY;
|
||||
packed_bitmap = TRUE;
|
||||
}
|
||||
else if ((magic_token[1] == '2') || (magic_token[1] == '5'))
|
||||
{
|
||||
raw = (magic_token[1] == '5');
|
||||
color_type = PNG_COLOR_TYPE_GRAY;
|
||||
if (maxval == 0)
|
||||
return FALSE;
|
||||
else if (maxval == 1)
|
||||
bit_depth = 1;
|
||||
else if (maxval <= 3)
|
||||
bit_depth = 2;
|
||||
|
|
@ -246,20 +275,13 @@ BOOL pnm2png (FILE *pnm_file, FILE *png_file, FILE *alpha_file,
|
|||
else /* maxval > 65535U */
|
||||
return FALSE;
|
||||
}
|
||||
else if ((type_token[1] == '3') || (type_token[1] == '6'))
|
||||
else if ((magic_token[1] == '3') || (magic_token[1] == '6'))
|
||||
{
|
||||
raw = (type_token[1] == '6');
|
||||
raw = (magic_token[1] == '6');
|
||||
color_type = PNG_COLOR_TYPE_RGB;
|
||||
get_token (pnm_file, width_token, sizeof (width_token));
|
||||
sscanf (width_token, "%lu", &ul_width);
|
||||
width = (png_uint_32) ul_width;
|
||||
get_token (pnm_file, height_token, sizeof (height_token));
|
||||
sscanf (height_token, "%lu", &ul_height);
|
||||
height = (png_uint_32) ul_height;
|
||||
get_token (pnm_file, maxval_token, sizeof (maxval_token));
|
||||
sscanf (maxval_token, "%lu", &ul_maxval);
|
||||
maxval = (png_uint_32) ul_maxval;
|
||||
if (maxval <= 1)
|
||||
if (maxval == 0)
|
||||
return FALSE;
|
||||
else if (maxval == 1)
|
||||
bit_depth = 1;
|
||||
else if (maxval <= 3)
|
||||
bit_depth = 2;
|
||||
|
|
@ -272,6 +294,11 @@ BOOL pnm2png (FILE *pnm_file, FILE *png_file, FILE *alpha_file,
|
|||
else /* maxval > 65535U */
|
||||
return FALSE;
|
||||
}
|
||||
else if (magic_token[1] == '7')
|
||||
{
|
||||
fprintf (stderr, "PNM2PNG can't read PAM (P7) files\n");
|
||||
return FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
return FALSE;
|
||||
|
|
@ -281,51 +308,36 @@ BOOL pnm2png (FILE *pnm_file, FILE *png_file, FILE *alpha_file,
|
|||
|
||||
if (alpha)
|
||||
{
|
||||
if (color_type == PNG_COLOR_TYPE_GRAY)
|
||||
color_type = PNG_COLOR_TYPE_GRAY_ALPHA;
|
||||
if (color_type == PNG_COLOR_TYPE_RGB)
|
||||
color_type = PNG_COLOR_TYPE_RGB_ALPHA;
|
||||
if ((fscan_pnm_magic (alpha_file, magic_token, sizeof (magic_token)) != 1)
|
||||
|| ((magic_token[1] != '2') && (magic_token[1] != '5')))
|
||||
return FALSE; /* not a PGM file */
|
||||
|
||||
get_token (alpha_file, type_token, sizeof (type_token));
|
||||
if (type_token[0] != 'P')
|
||||
{
|
||||
if ((fscan_pnm_uint_32 (alpha_file, &alpha_width) != 1) ||
|
||||
(fscan_pnm_uint_32 (alpha_file, &alpha_height) != 1) ||
|
||||
(fscan_pnm_uint_32 (alpha_file, &maxval) != 1))
|
||||
return FALSE; /* bad PGM file header */
|
||||
|
||||
if ((alpha_width != width) || (alpha_height != height))
|
||||
return FALSE; /* mismatched PGM dimensions */
|
||||
|
||||
alpha_raw = (magic_token[1] == '5');
|
||||
color_type |= PNG_COLOR_MASK_ALPHA;
|
||||
if (maxval == 0)
|
||||
return FALSE;
|
||||
}
|
||||
else if ((type_token[1] == '2') || (type_token[1] == '5'))
|
||||
{
|
||||
alpha_raw = (type_token[1] == '5');
|
||||
get_token (alpha_file, width_token, sizeof (width_token));
|
||||
sscanf (width_token, "%lu", &ul_alpha_width);
|
||||
alpha_width = (png_uint_32) ul_alpha_width;
|
||||
if (alpha_width != width)
|
||||
return FALSE;
|
||||
get_token (alpha_file, height_token, sizeof (height_token));
|
||||
sscanf (height_token, "%lu", &ul_alpha_height);
|
||||
alpha_height = (png_uint_32) ul_alpha_height;
|
||||
if (alpha_height != height)
|
||||
return FALSE;
|
||||
get_token (alpha_file, maxval_token, sizeof (maxval_token));
|
||||
sscanf (maxval_token, "%lu", &ul_maxval);
|
||||
maxval = (png_uint_32) ul_maxval;
|
||||
if (maxval <= 1)
|
||||
alpha_depth = 1;
|
||||
else if (maxval <= 3)
|
||||
alpha_depth = 2;
|
||||
else if (maxval <= 15)
|
||||
alpha_depth = 4;
|
||||
else if (maxval <= 255)
|
||||
alpha_depth = 8;
|
||||
else if (maxval <= 65535U)
|
||||
alpha_depth = 16;
|
||||
else /* maxval > 65535U */
|
||||
return FALSE;
|
||||
if (alpha_depth != bit_depth)
|
||||
return FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
else if (maxval == 1)
|
||||
alpha_depth = 1;
|
||||
else if (maxval <= 3)
|
||||
alpha_depth = 2;
|
||||
else if (maxval <= 15)
|
||||
alpha_depth = 4;
|
||||
else if (maxval <= 255)
|
||||
alpha_depth = 8;
|
||||
else if (maxval <= 65535U)
|
||||
alpha_depth = 16;
|
||||
else /* maxval > 65535U */
|
||||
return FALSE;
|
||||
if (alpha_depth != bit_depth)
|
||||
return FALSE;
|
||||
}
|
||||
} /* end if alpha */
|
||||
|
||||
/* calculate the number of channels and store alpha-presence */
|
||||
|
|
@ -337,21 +349,17 @@ BOOL pnm2png (FILE *pnm_file, FILE *png_file, FILE *alpha_file,
|
|||
channels = 3;
|
||||
else if (color_type == PNG_COLOR_TYPE_RGB_ALPHA)
|
||||
channels = 4;
|
||||
#if 0
|
||||
else
|
||||
channels = 0; /* cannot happen */
|
||||
#endif
|
||||
return FALSE; /* NOTREACHED */
|
||||
|
||||
alpha_present = (channels - 1) % 2;
|
||||
|
||||
#if defined(PNG_WRITE_INVERT_SUPPORTED) || defined(PNG_WRITE_PACK_SUPPORTED)
|
||||
if (packed_bitmap)
|
||||
{
|
||||
/* row data is as many bytes as can fit width x channels x bit_depth */
|
||||
row_bytes = (width * channels * bit_depth + 7) / 8;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
/* row_bytes is the width x number of channels x (bit-depth / 8) */
|
||||
row_bytes = width * channels * ((bit_depth <= 8) ? 1 : 2);
|
||||
|
|
@ -363,50 +371,59 @@ BOOL pnm2png (FILE *pnm_file, FILE *png_file, FILE *alpha_file,
|
|||
/* too big */
|
||||
return FALSE;
|
||||
}
|
||||
if ((png_pixels = (png_byte *)
|
||||
malloc ((size_t) row_bytes * (size_t) height)) == NULL)
|
||||
|
||||
/* allocate the rows using the same memory layout as libpng, and transfer
|
||||
* their ownership to libpng, with the responsibility to clean everything up;
|
||||
* please note the use of png_calloc instead of png_malloc */
|
||||
row_pointers = (png_byte **)
|
||||
png_calloc (png_ptr, height * sizeof (png_byte *));
|
||||
png_set_rows (png_ptr, info_ptr, row_pointers);
|
||||
png_data_freer (png_ptr, info_ptr, PNG_DESTROY_WILL_FREE_DATA, PNG_FREE_ALL);
|
||||
for (row = 0; row < height; row++)
|
||||
{
|
||||
/* out of memory */
|
||||
return FALSE;
|
||||
/* the individual rows should only be allocated after all the previous
|
||||
* steps completed successfully, because libpng must handle correctly
|
||||
* any image allocation left incomplete after an out-of-memory error */
|
||||
row_pointers[row] = (png_byte *) png_malloc (png_ptr, row_bytes);
|
||||
}
|
||||
|
||||
/* read data from PNM file */
|
||||
pix_ptr = png_pixels;
|
||||
/* read the data from PNM file */
|
||||
|
||||
for (row = 0; row < (int) height; row++)
|
||||
for (row = 0; row < height; row++)
|
||||
{
|
||||
#if defined(PNG_WRITE_INVERT_SUPPORTED) || defined(PNG_WRITE_PACK_SUPPORTED)
|
||||
pix_ptr = row_pointers[row];
|
||||
if (packed_bitmap)
|
||||
{
|
||||
for (i = 0; i < (int) row_bytes; i++)
|
||||
for (i = 0; i < row_bytes; i++)
|
||||
{
|
||||
/* png supports this format natively so no conversion is needed */
|
||||
*pix_ptr++ = get_data (pnm_file, 8);
|
||||
*pix_ptr++ = get_pnm_data (pnm_file, 8);
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
for (col = 0; col < (int) width; col++)
|
||||
for (col = 0; col < width; col++)
|
||||
{
|
||||
for (i = 0; i < (channels - alpha_present); i++)
|
||||
for (i = 0; i < (png_uint_32) (channels - alpha_present); i++)
|
||||
{
|
||||
if (raw)
|
||||
{
|
||||
*pix_ptr++ = get_data (pnm_file, bit_depth);
|
||||
*pix_ptr++ = get_pnm_data (pnm_file, bit_depth);
|
||||
if (bit_depth == 16)
|
||||
*pix_ptr++ = get_pnm_data (pnm_file, bit_depth);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (bit_depth <= 8)
|
||||
{
|
||||
*pix_ptr++ = get_value (pnm_file, bit_depth);
|
||||
*pix_ptr++ = get_pnm_value (pnm_file, bit_depth);
|
||||
}
|
||||
else
|
||||
{
|
||||
tmp16 = get_value (pnm_file, bit_depth);
|
||||
*pix_ptr = (png_byte) ((tmp16 >> 8) & 0xFF);
|
||||
val16 = get_pnm_value (pnm_file, bit_depth);
|
||||
*pix_ptr = (png_byte) ((val16 >> 8) & 0xFF);
|
||||
pix_ptr++;
|
||||
*pix_ptr = (png_byte) (tmp16 & 0xFF);
|
||||
*pix_ptr = (png_byte) (val16 & 0xFF);
|
||||
pix_ptr++;
|
||||
}
|
||||
}
|
||||
|
|
@ -416,19 +433,21 @@ BOOL pnm2png (FILE *pnm_file, FILE *png_file, FILE *alpha_file,
|
|||
{
|
||||
if (alpha_raw)
|
||||
{
|
||||
*pix_ptr++ = get_data (alpha_file, alpha_depth);
|
||||
*pix_ptr++ = get_pnm_data (alpha_file, alpha_depth);
|
||||
if (alpha_depth == 16)
|
||||
*pix_ptr++ = get_pnm_data (alpha_file, alpha_depth);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (alpha_depth <= 8)
|
||||
{
|
||||
*pix_ptr++ = get_value (alpha_file, bit_depth);
|
||||
*pix_ptr++ = get_pnm_value (alpha_file, bit_depth);
|
||||
}
|
||||
else
|
||||
{
|
||||
tmp16 = get_value (alpha_file, bit_depth);
|
||||
*pix_ptr++ = (png_byte) ((tmp16 >> 8) & 0xFF);
|
||||
*pix_ptr++ = (png_byte) (tmp16 & 0xFF);
|
||||
val16 = get_pnm_value (alpha_file, bit_depth);
|
||||
*pix_ptr++ = (png_byte) ((val16 >> 8) & 0xFF);
|
||||
*pix_ptr++ = (png_byte) (val16 & 0xFF);
|
||||
}
|
||||
}
|
||||
} /* end if alpha */
|
||||
|
|
@ -436,63 +455,19 @@ BOOL pnm2png (FILE *pnm_file, FILE *png_file, FILE *alpha_file,
|
|||
} /* end for col */
|
||||
} /* end for row */
|
||||
|
||||
/* prepare the standard PNG structures */
|
||||
png_ptr = png_create_write_struct (png_get_libpng_ver(NULL),
|
||||
NULL, NULL, NULL);
|
||||
if (!png_ptr)
|
||||
{
|
||||
free (png_pixels);
|
||||
return FALSE;
|
||||
}
|
||||
info_ptr = png_create_info_struct (png_ptr);
|
||||
if (!info_ptr)
|
||||
{
|
||||
png_destroy_write_struct (&png_ptr, NULL);
|
||||
free (png_pixels);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
#if defined(PNG_WRITE_INVERT_SUPPORTED) || defined(PNG_WRITE_PACK_SUPPORTED)
|
||||
if (packed_bitmap == TRUE)
|
||||
{
|
||||
png_set_packing (png_ptr);
|
||||
png_set_invert_mono (png_ptr);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (setjmp (png_jmpbuf (png_ptr)))
|
||||
{
|
||||
png_destroy_write_struct (&png_ptr, &info_ptr);
|
||||
free (png_pixels);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* initialize the png structure */
|
||||
png_init_io (png_ptr, png_file);
|
||||
|
||||
/* we're going to write more or less the same PNG as the input file */
|
||||
png_set_IHDR (png_ptr, info_ptr, width, height, bit_depth, color_type,
|
||||
(!interlace) ? PNG_INTERLACE_NONE : PNG_INTERLACE_ADAM7,
|
||||
PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
|
||||
|
||||
/* write the file header information */
|
||||
png_write_info (png_ptr, info_ptr);
|
||||
|
||||
/* if needed we will allocate memory for an new array of row-pointers */
|
||||
if (row_pointers == NULL)
|
||||
if (packed_bitmap == TRUE)
|
||||
{
|
||||
if ((row_pointers = (png_byte **)
|
||||
malloc (height * sizeof (png_byte *))) == NULL)
|
||||
{
|
||||
png_destroy_write_struct (&png_ptr, &info_ptr);
|
||||
free (png_pixels);
|
||||
return FALSE;
|
||||
}
|
||||
png_set_packing (png_ptr);
|
||||
png_set_invert_mono (png_ptr);
|
||||
}
|
||||
|
||||
/* set the individual row_pointers to point at the correct offsets */
|
||||
for (i = 0; i < (int) height; i++)
|
||||
row_pointers[i] = png_pixels + i * row_bytes;
|
||||
/* write the file header information */
|
||||
png_write_info (png_ptr, info_ptr);
|
||||
|
||||
/* write out the entire image data in one call */
|
||||
png_write_image (png_ptr, row_pointers);
|
||||
|
|
@ -500,22 +475,46 @@ BOOL pnm2png (FILE *pnm_file, FILE *png_file, FILE *alpha_file,
|
|||
/* write the additional chunks to the PNG file (not really needed) */
|
||||
png_write_end (png_ptr, info_ptr);
|
||||
|
||||
/* clean up after the write, and free any memory allocated */
|
||||
png_destroy_write_struct (&png_ptr, &info_ptr);
|
||||
|
||||
if (row_pointers != NULL)
|
||||
free (row_pointers);
|
||||
if (png_pixels != NULL)
|
||||
free (png_pixels);
|
||||
|
||||
return TRUE;
|
||||
} /* end of pnm2png */
|
||||
|
||||
/*
|
||||
* get_token - gets the first string after whitespace
|
||||
* fscan_pnm_magic - like fscan_pnm_token below, but expects the magic string
|
||||
* to start immediately, without any comment or whitespace,
|
||||
* and to match the regex /^P[1-9]$/
|
||||
*/
|
||||
|
||||
void get_token (FILE *pnm_file, char *token_buf, size_t token_buf_size)
|
||||
int fscan_pnm_magic (FILE *pnm_file, char *magic_buf, size_t magic_buf_size)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = fgetc (pnm_file);
|
||||
if (ret == EOF) return 0;
|
||||
ungetc (ret, pnm_file);
|
||||
if (ret != 'P') return 0;
|
||||
|
||||
/* the string buffer must be at least four bytes long, i.e., the capacity
|
||||
* required for strings of at least three characters long, i.e., the minimum
|
||||
* required for ensuring that our magic string is exactly two characters long
|
||||
*/
|
||||
if (magic_buf_size < 4) return -1;
|
||||
|
||||
ret = fscan_pnm_token (pnm_file, magic_buf, magic_buf_size);
|
||||
if (ret < 1) return ret;
|
||||
|
||||
if ((magic_buf[1] < '1') || (magic_buf[1] > '9')) return 0;
|
||||
if (magic_buf[2] != '\0') return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* fscan_pnm_token - extracts the first string token after whitespace,
|
||||
* and (like fscanf) returns the number of successful
|
||||
* extractions, which can be either 0 or 1
|
||||
*/
|
||||
|
||||
int fscan_pnm_token (FILE *pnm_file, char *token_buf, size_t token_buf_size)
|
||||
{
|
||||
size_t i = 0;
|
||||
int ret;
|
||||
|
|
@ -543,29 +542,66 @@ void get_token (FILE *pnm_file, char *token_buf, size_t token_buf_size)
|
|||
{
|
||||
ret = fgetc (pnm_file);
|
||||
if (ret == EOF) break;
|
||||
if (ret == '0')
|
||||
{
|
||||
/* avoid storing more than one leading '0' in the token buffer,
|
||||
* to ensure that all valid (in-range) numeric inputs can fit in. */
|
||||
if ((i == 0) && (token_buf[i] == '0')) continue;
|
||||
}
|
||||
if (++i == token_buf_size - 1) break;
|
||||
token_buf[i] = (char) ret;
|
||||
}
|
||||
while ((ret != '\n') && (ret != '\r') && (ret != ' '));
|
||||
|
||||
token_buf[i] = '\0';
|
||||
|
||||
return;
|
||||
return (i > 0) ? 1 : 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* get_data - takes first byte and converts into next pixel value,
|
||||
* taking as much bits as defined by bit-depth and
|
||||
* using the bit-depth to fill up a byte (0Ah -> AAh)
|
||||
* fscan_pnm_uint_32 - like fscan_token above, but expects the extracted token
|
||||
* to be numeric, and converts it to an unsigned 32-bit int
|
||||
*/
|
||||
|
||||
png_uint_32 get_data (FILE *pnm_file, int depth)
|
||||
int fscan_pnm_uint_32 (FILE *pnm_file, png_uint_32 *num_ptr)
|
||||
{
|
||||
char token[16];
|
||||
unsigned long token_value;
|
||||
int ret;
|
||||
|
||||
ret = fscan_pnm_token (pnm_file, token, sizeof (token));
|
||||
if (ret < 1) return ret;
|
||||
|
||||
if ((token[0] < '0') && (token[0] > '9'))
|
||||
return 0; /* the token starts with junk, or a +/- sign, which is invalid */
|
||||
|
||||
ret = sscanf (token, "%lu%*c", &token_value);
|
||||
if (ret != 1)
|
||||
return 0; /* the token ends with junk */
|
||||
|
||||
*num_ptr = (png_uint_32) token_value;
|
||||
|
||||
#if ULONG_MAX > 0xFFFFFFFFUL
|
||||
/* saturate the converted number, following the fscanf convention */
|
||||
if (token_value > 0xFFFFFFFFUL)
|
||||
*num_ptr = 0xFFFFFFFFUL;
|
||||
#endif
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* get_pnm_data - takes first byte and converts into next pixel value,
|
||||
* taking as many bits as defined by bit-depth and
|
||||
* using the bit-depth to fill up a byte (0x0A -> 0xAA)
|
||||
*/
|
||||
|
||||
png_uint_32 get_pnm_data (FILE *pnm_file, int depth)
|
||||
{
|
||||
static int bits_left = 0;
|
||||
static int old_value = 0;
|
||||
static int mask = 0;
|
||||
int i;
|
||||
png_uint_32 ret_value;
|
||||
int i;
|
||||
|
||||
if (mask == 0)
|
||||
for (i = 0; i < depth; i++)
|
||||
|
|
@ -573,7 +609,11 @@ png_uint_32 get_data (FILE *pnm_file, int depth)
|
|||
|
||||
if (bits_left <= 0)
|
||||
{
|
||||
/* FIXME:
|
||||
* signal the premature end of file, instead of pretending to read zeroes
|
||||
*/
|
||||
old_value = fgetc (pnm_file);
|
||||
if (old_value == EOF) return 0;
|
||||
bits_left = 8;
|
||||
}
|
||||
|
||||
|
|
@ -588,25 +628,28 @@ png_uint_32 get_data (FILE *pnm_file, int depth)
|
|||
}
|
||||
|
||||
/*
|
||||
* get_value - takes first (numeric) string and converts into number,
|
||||
* using the bit-depth to fill up a byte (0Ah -> AAh)
|
||||
* get_pnm_value - takes first (numeric) string and converts into number,
|
||||
* using the bit-depth to fill up a byte (0x0A -> 0xAA)
|
||||
*/
|
||||
|
||||
png_uint_32 get_value (FILE *pnm_file, int depth)
|
||||
png_uint_32 get_pnm_value (FILE *pnm_file, int depth)
|
||||
{
|
||||
static png_uint_32 mask = 0;
|
||||
char token[16];
|
||||
unsigned long ul_ret_value;
|
||||
png_uint_32 ret_value;
|
||||
int i = 0;
|
||||
int i;
|
||||
|
||||
if (mask == 0)
|
||||
for (i = 0; i < depth; i++)
|
||||
mask = (mask << 1) | 0x01;
|
||||
|
||||
get_token (pnm_file, token, sizeof (token));
|
||||
sscanf (token, "%lu", &ul_ret_value);
|
||||
ret_value = (png_uint_32) ul_ret_value;
|
||||
if (fscan_pnm_uint_32 (pnm_file, &ret_value) != 1)
|
||||
{
|
||||
/* FIXME:
|
||||
* signal the invalid numeric tokens or the premature end of file,
|
||||
* instead of pretending to read zeroes
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
ret_value &= mask;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
pngsuite
|
||||
--------
|
||||
Copyright (c) Willem van Schaik, 1999, 2011, 2012
|
||||
|
|
|
|||
|
|
@ -1,2 +1 @@
|
|||
|
||||
These images fail the "pngimage-quick" and "pngimage-full" tests.
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@
|
|||
*
|
||||
* Copyright (c) 2017 Glenn Randers-Pehrson
|
||||
* Written by Vadim Barkov, 2017.
|
||||
* Last changed in libpng 1.6.29 [March 16, 2017]
|
||||
*
|
||||
* This code is released under the libpng license.
|
||||
* For conditions of distribution and use, see the disclaimer
|
||||
|
|
@ -12,7 +11,7 @@
|
|||
* BUG REPORTS: png-mng-implement@sourceforge.net
|
||||
*
|
||||
* png_have_vsx implemented for Linux by reading the widely available
|
||||
* pseudo-file /proc/cpuinfo.
|
||||
* pseudo-file /proc/cpuinfo.
|
||||
*
|
||||
* This code is strict ANSI-C and is probably moderately portable; it does
|
||||
* however use <stdio.h> and it assumes that /proc/cpuinfo is never localized.
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@
|
|||
*
|
||||
* Copyright (c) 2017 Glenn Randers-Pehrson
|
||||
* Written by Vadim Barkov, 2017.
|
||||
* Last changed in libpng 1.6.29 [March 16, 2017]
|
||||
*
|
||||
* This code is released under the libpng license.
|
||||
* For conditions of distribution and use, see the disclaimer
|
||||
|
|
|
|||
BIN
Engine/lib/lpng/contrib/testpngs/badpal/regression-palette-8.png
Normal file
|
After Width: | Height: | Size: 1 KiB |
BIN
Engine/lib/lpng/contrib/testpngs/badpal/small-palette-1.png
Normal file
|
After Width: | Height: | Size: 271 B |
BIN
Engine/lib/lpng/contrib/testpngs/badpal/small-palette-2.png
Normal file
|
After Width: | Height: | Size: 277 B |
BIN
Engine/lib/lpng/contrib/testpngs/badpal/small-palette-4.png
Normal file
|
After Width: | Height: | Size: 315 B |
BIN
Engine/lib/lpng/contrib/testpngs/badpal/small-palette-8.png
Normal file
|
After Width: | Height: | Size: 1 KiB |
BIN
Engine/lib/lpng/contrib/testpngs/badpal/test-palette-1.png
Normal file
|
After Width: | Height: | Size: 432 B |
BIN
Engine/lib/lpng/contrib/testpngs/badpal/test-palette-2.png
Normal file
|
After Width: | Height: | Size: 499 B |
BIN
Engine/lib/lpng/contrib/testpngs/badpal/test-palette-4.png
Normal file
|
After Width: | Height: | Size: 591 B |
BIN
Engine/lib/lpng/contrib/testpngs/badpal/test-palette-8.png
Normal file
|
After Width: | Height: | Size: 2.7 KiB |
|
|
@ -1,12 +1,10 @@
|
|||
#!/bin/sh
|
||||
#
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Make a set of test PNG files, MAKEPNG is the name of the makepng executable
|
||||
# built from contrib/libtests/makepng.c
|
||||
|
||||
# Copyright (c) 2015 John Cunningham Bowler
|
||||
|
||||
# Last changed in libpng 1.6.20 [December 3, 2015]
|
||||
|
||||
# This code is released under the libpng license.
|
||||
# For conditions of distribution and use, see the disclaimer
|
||||
# and license in png.h
|
||||
|
|
|
|||
|
After Width: | Height: | Size: 142 B |
|
|
@ -2,8 +2,6 @@
|
|||
*
|
||||
* Copyright (c) 2013 John Cunningham Bowler
|
||||
*
|
||||
* Last changed in libpng 1.6.0 [February 14, 2013]
|
||||
*
|
||||
* This code is released under the libpng license.
|
||||
* For conditions of distribution and use, see the disclaimer
|
||||
* and license in png.h
|
||||
|
|
@ -11,8 +9,8 @@
|
|||
* Generate crc32 and adler32 checksums of the given input files, used to
|
||||
* generate check-codes for use when matching ICC profiles within libpng.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <zlib.h>
|
||||
|
||||
static int
|
||||
|
|
|
|||
|
|
@ -1,144 +0,0 @@
|
|||
#!/bin/sh
|
||||
|
||||
# chkfmt
|
||||
#
|
||||
# COPYRIGHT: Written by John Cunningham Bowler, 2010.
|
||||
# To the extent possible under law, the author has waived all copyright and
|
||||
# related or neighboring rights to this work. This work is published from:
|
||||
# United States.
|
||||
#
|
||||
# Check the format of the source files in the current directory - checks for a
|
||||
# line length of 80 characters max and no tab characters.
|
||||
#
|
||||
# Optionally arguments are files or directories to check.
|
||||
#
|
||||
# -v: output the long lines (makes fixing them easier)
|
||||
# -e: spawn an editor for each file that needs a change ($EDITOR must be
|
||||
# defined). When using -e the script MUST be run from an interactive
|
||||
# command line.
|
||||
verbose=
|
||||
edit=
|
||||
vers=
|
||||
test "$1" = "-v" && {
|
||||
shift
|
||||
verbose=yes
|
||||
}
|
||||
test "$1" = "-e" && {
|
||||
shift
|
||||
if test -n "$EDITOR"
|
||||
then
|
||||
edit=yes
|
||||
|
||||
# Copy the standard streams for the editor
|
||||
exec 3>&0 4>&1 5>&2
|
||||
else
|
||||
echo "chkfmt -e: EDITOR must be defined" >&2
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Function to edit a single file - if the file isn't changed ask the user
|
||||
# whether or not to continue. This stuff only works if the script is run from
|
||||
# the command line (otherwise, don't specify -e or you will be sorry).
|
||||
doed(){
|
||||
cp "$file" "$file".orig
|
||||
"$EDITOR" "$file" 0>&3 1>&4 2>&5 3>&- 4>&- 5>&- || exit 1
|
||||
if cmp -s "$file".orig "$file"
|
||||
then
|
||||
rm "$file".orig
|
||||
echo -n "$file: file not changed, type anything to continue: " >&5
|
||||
read ans 0>&3
|
||||
test -n "$ans" || return 1
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
# In beta versions the version string which appears in files can be a little
|
||||
# long and cause spuriously overlong lines. To avoid this substitute the version
|
||||
# string with a 'standard' version a.b.cc before checking for long lines.
|
||||
if test -r png.h
|
||||
then
|
||||
vers="`sed -n -e \
|
||||
's/^#define PNG_LIBPNG_VER_STRING .\([0-9]\.[0-9]\.[0-9][0-9a-z]*\).$/\1/p' \
|
||||
png.h`"
|
||||
echo "chkfmt: checking version $vers"
|
||||
fi
|
||||
if test -z "$vers"
|
||||
then
|
||||
echo "chkfmt: png.h not found, ignoring version number" >&2
|
||||
fi
|
||||
|
||||
test -n "$1" || set -- .
|
||||
find "$@" \( -type d \( -name '.git' -o -name '.libs' -o -name 'projects' \) \
|
||||
-prune \) -o \( -type f \
|
||||
! -name '*.[oa]' ! -name '*.l[oa]' ! -name '*.png' ! -name '*.out' \
|
||||
! -name '*.jpg' ! -name '*.patch' ! -name '*.obj' ! -name '*.exe' \
|
||||
! -name '*.com' ! -name '*.tar.*' ! -name '*.zip' ! -name '*.ico' \
|
||||
! -name '*.res' ! -name '*.rc' ! -name '*.mms' ! -name '*.rej' \
|
||||
! -name '*.dsp' ! -name '*.orig' ! -name '*.dfn' ! -name '*.swp' \
|
||||
! -name '~*' ! -name '*.3' \
|
||||
! -name 'missing' ! -name 'mkinstalldirs' ! -name 'depcomp' \
|
||||
! -name 'aclocal.m4' ! -name 'install-sh' ! -name 'Makefile.in' \
|
||||
! -name 'ltmain.sh' ! -name 'config*' -print \) | {
|
||||
st=0
|
||||
while read file
|
||||
do
|
||||
case "$file" in
|
||||
*.mak|*[Mm]akefile.*|*[Mm]akefile)
|
||||
# Makefiles require tabs, dependency lines can be this long.
|
||||
check_tabs=
|
||||
line_length=100;;
|
||||
*.awk)
|
||||
# Includes literal tabs
|
||||
check_tabs=
|
||||
# The following is arbitrary
|
||||
line_length=132;;
|
||||
*contrib/*/*.[ch])
|
||||
check_tabs=yes
|
||||
line_length=96;;
|
||||
*)
|
||||
check_tabs=yes
|
||||
line_length=80;;
|
||||
esac
|
||||
|
||||
# Note that vers can only contain 0-9, . and a-z
|
||||
if test -n "$vers"
|
||||
then
|
||||
sed -e "s/$vers/a.b.cc/g" "$file" >"$file".$$
|
||||
else
|
||||
cp "$file" "$file".$$
|
||||
fi
|
||||
splt="`fold -$line_length "$file".$$ | diff -c "$file".$$ -`"
|
||||
rm "$file".$$
|
||||
|
||||
if test -n "$splt"
|
||||
then
|
||||
echo "$file: lines too long"
|
||||
st=1
|
||||
if test -n "$EDITOR" -a -n "$edit"
|
||||
then
|
||||
doed "$file" || exit 1
|
||||
elif test -n "$verbose"
|
||||
then
|
||||
echo "$splt"
|
||||
fi
|
||||
fi
|
||||
if test -n "$check_tabs"
|
||||
then
|
||||
tab="`tr -c -d '\t' <"$file"`"
|
||||
if test -n "$tab"
|
||||
then
|
||||
echo "$file: file contains tab characters"
|
||||
st=1
|
||||
if test -n "$EDITOR" -a -n "$edit"
|
||||
then
|
||||
doed "$file" || exit 1
|
||||
elif test -n "$verbose"
|
||||
then
|
||||
echo "$splt"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
done
|
||||
exit $st
|
||||
}
|
||||
|
|
@ -1,7 +1,4 @@
|
|||
/*-
|
||||
* convert.c
|
||||
*
|
||||
* Last changed in libpng 1.6.0 [February 14, 2013]
|
||||
/* convert.c
|
||||
*
|
||||
* COPYRIGHT: Written by John Cunningham Bowler, 2013.
|
||||
* To the extent possible under law, the author has waived all copyright and
|
||||
|
|
@ -10,6 +7,7 @@
|
|||
*
|
||||
* Convert 8-bit sRGB or 16-bit linear values to another format.
|
||||
*/
|
||||
|
||||
#define _ISOC99_SOURCE 1
|
||||
|
||||
#include <stdlib.h>
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
/*- genpng
|
||||
/* genpng
|
||||
*
|
||||
* COPYRIGHT: Written by John Cunningham Bowler, 2015.
|
||||
* Revised by Glenn Randers-Pehrson, 2017, to add buffer-size check.
|
||||
|
|
@ -69,6 +69,7 @@
|
|||
* joins are mitres; the outside of the lines are continued to the point of
|
||||
* intersection.
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
|
@ -453,7 +454,7 @@ check_square(const struct arg *arg, double x, double y)
|
|||
* { inside_circle_filled, check_circle_filled },
|
||||
* { inside_circle, check_circle }
|
||||
*
|
||||
* The functions here are analoguous to the square ones; however, they check
|
||||
* The functions here are analogous to the square ones; however, they check
|
||||
* the corresponding ellipse as opposed to the rectangle.
|
||||
*/
|
||||
static int
|
||||
|
|
|
|||
|
|
@ -1,13 +1,11 @@
|
|||
#!/bin/sh
|
||||
#
|
||||
|
||||
# intgamma.sh
|
||||
#
|
||||
# Last changed in libpng 1.6.0 [February 14, 2013]
|
||||
#
|
||||
# COPYRIGHT: Written by John Cunningham Bowler, 2013.
|
||||
# To the extent possible under law, the author has waived all copyright and
|
||||
# related or neighboring rights to this work. This work is published from:
|
||||
# United States.
|
||||
# related or neighboring rights to this work. The author published this work
|
||||
# from the United States.
|
||||
#
|
||||
# Shell script to generate png.c 8-bit and 16-bit log tables (see the code in
|
||||
# png.c for details).
|
||||
|
|
@ -17,11 +15,11 @@
|
|||
# (0..255) value and a similar table for the exponent calculation.
|
||||
#
|
||||
# "bc" must be on the path when the script is executed, and the math library
|
||||
# (-lm) must be available
|
||||
#
|
||||
# function to print out a list of numbers as integers; the function truncates
|
||||
# the integers which must be one-per-line
|
||||
function print(){
|
||||
# (-lm) must be available.
|
||||
|
||||
# Function to print out a list of numbers as integers; the function truncates
|
||||
# the integers which must be one-per-line.
|
||||
print(){
|
||||
awk 'BEGIN{
|
||||
str = ""
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,4 @@
|
|||
/* makesRGB.c -- build sRGB-to-linear and linear-to-sRGB conversion tables
|
||||
*
|
||||
* Last changed in libpng 1.6.0 [February 14, 2013]
|
||||
*
|
||||
* COPYRIGHT: Written by John Cunningham Bowler, 2013.
|
||||
* To the extent possible under law, the author has waived all copyright and
|
||||
|
|
@ -14,6 +12,7 @@
|
|||
* approximation to the 8-bit sRGB encoded value. Calculate the error in these
|
||||
* tables and display it.
|
||||
*/
|
||||
|
||||
#define _C99_SOURCE 1
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
|
|
|
|||
|
|
@ -1,8 +1,6 @@
|
|||
|
||||
/* png-fix-itxt version 1.0.0
|
||||
/* png-fix-itxt
|
||||
*
|
||||
* Copyright 2015 Glenn Randers-Pehrson
|
||||
* Last changed in libpng 1.6.18 [July 23, 2015]
|
||||
*
|
||||
* This code is released under the libpng license.
|
||||
* For conditions of distribution and use, see the disclaimer
|
||||
|
|
@ -10,7 +8,7 @@
|
|||
*
|
||||
* Usage:
|
||||
*
|
||||
* png-fix-itxt.exe < bad.png > good.png
|
||||
* png-fix-itxt < bad.png > good.png
|
||||
*
|
||||
* Fixes a PNG file written with libpng-1.6.0 or 1.6.1 that has one or more
|
||||
* uncompressed iTXt chunks. Assumes that the actual length is greater
|
||||
|
|
|
|||
|
|
@ -1,8 +1,6 @@
|
|||
/* pngcp.c
|
||||
*
|
||||
* Copyright (c) 2016 John Cunningham Bowler
|
||||
*
|
||||
* Last changed in libpng 1.6.24 [August 4, 2016]
|
||||
* Copyright (c) 2016,2022,2024 John Cunningham Bowler
|
||||
*
|
||||
* This code is released under the libpng license.
|
||||
* For conditions of distribution and use, see the disclaimer
|
||||
|
|
@ -14,7 +12,12 @@
|
|||
*
|
||||
* For a more extensive example that uses the transforms see
|
||||
* contrib/libtests/pngimage.c in the libpng distribution.
|
||||
*
|
||||
* This code is not intended for installation in a release system; the command
|
||||
* line options are not documented and most of the behavior is intended for
|
||||
* testing libpng performance, both speed and compression.
|
||||
*/
|
||||
|
||||
#include "pnglibconf.h" /* To find how libpng was configured. */
|
||||
|
||||
#ifdef PNG_PNGCP_TIMING_SUPPORTED
|
||||
|
|
@ -85,16 +88,6 @@
|
|||
# define voidcast(type, value) (value)
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#ifdef __GNUC__
|
||||
/* Many versions of GCC erroneously report that local variables unmodified
|
||||
* within the scope of a setjmp may be clobbered. This hacks round the
|
||||
* problem (sometimes) without harming other compilers.
|
||||
*/
|
||||
# define gv volatile
|
||||
#else
|
||||
# define gv
|
||||
#endif
|
||||
|
||||
/* 'CLOCK_PROCESS_CPUTIME_ID' is one of the clock timers for clock_gettime. It
|
||||
* need not be supported even when clock_gettime is available. It returns the
|
||||
* 'CPU' time the process has consumed. 'CPU' time is assumed to include time
|
||||
|
|
@ -336,7 +329,7 @@ static const option options[] =
|
|||
# define VLC(name) VLCIDAT(name) VLCiCCP(name) VLCzTXt(name)
|
||||
|
||||
# ifdef PNG_SW_COMPRESS_png_level
|
||||
/* The libpng compression level isn't searched because it justs sets the
|
||||
/* The libpng compression level isn't searched because it just sets the
|
||||
* other things that are searched!
|
||||
*/
|
||||
VLO("compression", compression, 0)
|
||||
|
|
@ -392,6 +385,7 @@ struct display
|
|||
{
|
||||
jmp_buf error_return; /* Where to go to on error */
|
||||
unsigned int errset; /* error_return is set */
|
||||
int errlevel; /* error level from longjmp */
|
||||
|
||||
const char *operation; /* What is happening */
|
||||
const char *filename; /* The name of the original file */
|
||||
|
|
@ -503,10 +497,10 @@ display_init(struct display *dp)
|
|||
}
|
||||
|
||||
static void
|
||||
display_clean_read(struct display *dp)
|
||||
display_clean_read(struct display *dp, int freeinfo)
|
||||
{
|
||||
if (dp->read_pp != NULL)
|
||||
png_destroy_read_struct(&dp->read_pp, NULL, NULL);
|
||||
png_destroy_read_struct(&dp->read_pp, freeinfo ? &dp->ip : NULL, NULL);
|
||||
|
||||
if (dp->fp != NULL)
|
||||
{
|
||||
|
|
@ -517,7 +511,7 @@ display_clean_read(struct display *dp)
|
|||
}
|
||||
|
||||
static void
|
||||
display_clean_write(struct display *dp)
|
||||
display_clean_write(struct display *dp, int freeinfo)
|
||||
{
|
||||
if (dp->fp != NULL)
|
||||
{
|
||||
|
|
@ -527,14 +521,14 @@ display_clean_write(struct display *dp)
|
|||
}
|
||||
|
||||
if (dp->write_pp != NULL)
|
||||
png_destroy_write_struct(&dp->write_pp, dp->tsp > 0 ? NULL : &dp->ip);
|
||||
png_destroy_write_struct(&dp->write_pp, freeinfo ? &dp->ip : NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
display_clean(struct display *dp)
|
||||
{
|
||||
display_clean_read(dp);
|
||||
display_clean_write(dp);
|
||||
display_clean_read(dp, 1/*freeinfo*/);
|
||||
display_clean_write(dp, 1/*freeinfo*/);
|
||||
dp->output_file = NULL;
|
||||
|
||||
# if PNG_LIBPNG_VER < 10700 && defined PNG_TEXT_SUPPORTED
|
||||
|
|
@ -631,7 +625,10 @@ display_log(struct display *dp, error_level level, const char *fmt, ...)
|
|||
if (level > APP_FAIL || (level > ERRORS && !(dp->options & CONTINUE)))
|
||||
{
|
||||
if (dp->errset)
|
||||
{
|
||||
dp->errlevel = level;
|
||||
longjmp(dp->error_return, level);
|
||||
}
|
||||
|
||||
else
|
||||
exit(99);
|
||||
|
|
@ -778,7 +775,7 @@ static void
|
|||
set_opt_string(struct display *dp, unsigned int sp)
|
||||
/* Add the appropriate option string to dp->curr. */
|
||||
{
|
||||
dp->stack[sp].opt_string_end = set_opt_string_(dp, sp, dp->stack[sp].opt,
|
||||
dp->stack[sp].opt_string_end = set_opt_string_(dp, sp, dp->stack[sp].opt,
|
||||
options[dp->stack[sp].opt].values[dp->stack[sp].entry].name);
|
||||
}
|
||||
|
||||
|
|
@ -1745,7 +1742,17 @@ read_function(png_structp pp, png_bytep data, size_t size)
|
|||
static void
|
||||
read_png(struct display *dp, const char *filename)
|
||||
{
|
||||
display_clean_read(dp); /* safety */
|
||||
/* This is an assumption of the code; it may happen if a previous write fails
|
||||
* and there is a bug in the cleanup handling below (look for setjmp).
|
||||
* Passing freeinfo==1 to display_clean_read below avoids a second error
|
||||
* on dp->ip != NULL below.
|
||||
*/
|
||||
if (dp->read_pp != NULL)
|
||||
{
|
||||
display_log(dp, APP_FAIL, "unexpected png_read_struct");
|
||||
display_clean_read(dp, 1/*freeinfo*/); /* recovery */
|
||||
}
|
||||
|
||||
display_start_read(dp, filename);
|
||||
|
||||
dp->read_pp = png_create_read_struct(PNG_LIBPNG_VER_STRING, dp,
|
||||
|
|
@ -1769,6 +1776,13 @@ read_png(struct display *dp, const char *filename)
|
|||
png_set_check_for_invalid_index(dp->read_pp, -1/*off completely*/);
|
||||
# endif /* IGNORE_INDEX */
|
||||
|
||||
if (dp->ip != NULL)
|
||||
{
|
||||
/* UNEXPECTED: some problem in the display_clean function calls! */
|
||||
display_log(dp, APP_FAIL, "read_png: freeing old info struct");
|
||||
png_destroy_info_struct(dp->read_pp, &dp->ip);
|
||||
}
|
||||
|
||||
/* The png_read_png API requires us to make the info struct, but it does the
|
||||
* call to png_read_info.
|
||||
*/
|
||||
|
|
@ -1848,7 +1862,14 @@ read_png(struct display *dp, const char *filename)
|
|||
}
|
||||
#endif /* FIX_INDEX */
|
||||
|
||||
display_clean_read(dp);
|
||||
/* NOTE: dp->ip is where all the information about the PNG that was just read
|
||||
* is stored. It can be used to write and write again a single PNG file,
|
||||
* however be aware that prior to libpng 1.7 text chunks could only be
|
||||
* written once; this is a bug which would require a significant code rewrite
|
||||
* to fix, it has been there in several versions of libpng (it was introduced
|
||||
* to fix another bug involving duplicate writes of the text chunks.)
|
||||
*/
|
||||
display_clean_read(dp, 0/*freeiinfo*/);
|
||||
dp->operation = "none";
|
||||
}
|
||||
|
||||
|
|
@ -1975,7 +1996,21 @@ set_text_compression(struct display *dp)
|
|||
static void
|
||||
write_png(struct display *dp, const char *destname)
|
||||
{
|
||||
display_clean_write(dp); /* safety */
|
||||
/* If this test fails png_write_png would fail *silently* below; this
|
||||
* is not helpful, so catch the problem now and give up:
|
||||
*/
|
||||
if (dp->ip == NULL)
|
||||
display_log(dp, INTERNAL_ERROR, "missing png_info");
|
||||
|
||||
/* This is an assumption of the code; it may happen if a previous
|
||||
* write fails and there is a bug in the cleanup handling below.
|
||||
*/
|
||||
if (dp->write_pp != NULL)
|
||||
{
|
||||
display_log(dp, APP_FAIL, "unexpected png_write_struct");
|
||||
display_clean_write(dp, 0/*!freeinfo*/);
|
||||
}
|
||||
|
||||
display_start_write(dp, destname);
|
||||
|
||||
dp->write_pp = png_create_write_struct(PNG_LIBPNG_VER_STRING, dp,
|
||||
|
|
@ -2073,10 +2108,6 @@ write_png(struct display *dp, const char *destname)
|
|||
destname == NULL ? "stdout" : destname, strerror(errno));
|
||||
}
|
||||
|
||||
/* Clean it on the way out - if control returns to the caller then the
|
||||
* written_file contains the required data.
|
||||
*/
|
||||
display_clean_write(dp);
|
||||
dp->operation = "none";
|
||||
}
|
||||
|
||||
|
|
@ -2243,6 +2274,10 @@ cp_one_file(struct display *dp, const char *filename, const char *destname)
|
|||
/* Loop to find the best option. */
|
||||
do
|
||||
{
|
||||
/* Clean before each write_png; this just removes *dp->write_pp which
|
||||
* cannot be reused.
|
||||
*/
|
||||
display_clean_write(dp, 0/*!freeinfo*/);
|
||||
write_png(dp, tmpname);
|
||||
|
||||
/* And compare the sizes (the write function makes sure write_size
|
||||
|
|
@ -2272,17 +2307,14 @@ cp_one_file(struct display *dp, const char *filename, const char *destname)
|
|||
/* Do this for the 'sizes' option so that it reports the correct size. */
|
||||
dp->write_size = dp->best_size;
|
||||
}
|
||||
|
||||
display_clean_write(dp, 1/*freeinfo*/);
|
||||
}
|
||||
|
||||
static int
|
||||
cppng(struct display *dp, const char *file, const char *gv dest)
|
||||
/* Exists solely to isolate the setjmp clobbers which some versions of GCC
|
||||
* erroneously generate.
|
||||
*/
|
||||
cppng(struct display *dp, const char *file, const char *dest)
|
||||
{
|
||||
int ret = setjmp(dp->error_return);
|
||||
|
||||
if (ret == 0)
|
||||
if (setjmp(dp->error_return) == 0)
|
||||
{
|
||||
dp->errset = 1;
|
||||
cp_one_file(dp, file, dest);
|
||||
|
|
@ -2294,10 +2326,11 @@ cppng(struct display *dp, const char *file, const char *gv dest)
|
|||
{
|
||||
dp->errset = 0;
|
||||
|
||||
if (ret < ERRORS) /* shouldn't longjmp on warnings */
|
||||
display_log(dp, INTERNAL_ERROR, "unexpected return code %d", ret);
|
||||
if (dp->errlevel < ERRORS) /* shouldn't longjmp on warnings */
|
||||
display_log(dp, INTERNAL_ERROR, "unexpected return code %d",
|
||||
dp->errlevel);
|
||||
|
||||
return ret;
|
||||
return dp->errlevel;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
/* pngfix.c
|
||||
*
|
||||
* Last changed in libpng 1.6.31 [July 27, 2017]
|
||||
* Copyright (c) 2014-2017 John Cunningham Bowler
|
||||
* Copyright (c) 2014-2017,2024 John Cunningham Bowler
|
||||
*
|
||||
* This code is released under the libpng license.
|
||||
* For conditions of distribution and use, see the disclaimer
|
||||
|
|
@ -10,6 +9,7 @@
|
|||
* Tool to check and fix the zlib inflate 'too far back' problem.
|
||||
* See the usage message for more information.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
|
@ -20,19 +20,6 @@
|
|||
|
||||
#define implies(x,y) assert(!(x) || (y))
|
||||
|
||||
#ifdef __GNUC__
|
||||
/* This is used to fix the error:
|
||||
*
|
||||
* pngfix.c:
|
||||
* In function 'zlib_advance':
|
||||
* pngfix.c:181:13: error: assuming signed overflow does not
|
||||
* occur when simplifying conditional to constant [-Werror=strict-overflow]
|
||||
*/
|
||||
# define FIX_GCC volatile
|
||||
#else
|
||||
# define FIX_GCC
|
||||
#endif
|
||||
|
||||
#define PROGRAM_NAME "pngfix"
|
||||
|
||||
/* Define the following to use this program against your installed libpng,
|
||||
|
|
@ -45,7 +32,7 @@
|
|||
#endif
|
||||
|
||||
#if PNG_LIBPNG_VER < 10603 /* 1.6.3 */
|
||||
# error "pngfix will not work with libpng prior to 1.6.3"
|
||||
# error pngfix requires libpng version 1.6.3 or newer
|
||||
#endif
|
||||
|
||||
#ifdef PNG_SETJMP_SUPPORTED
|
||||
|
|
@ -81,7 +68,7 @@
|
|||
#endif
|
||||
|
||||
#ifndef PNG_MAXIMUM_INFLATE_WINDOW
|
||||
# error "pngfix not supported in this libpng version"
|
||||
# error pngfix requires libpng with PNG_MAXIMUM_INFLATE_WINDOW supported
|
||||
#endif
|
||||
|
||||
#if ZLIB_VERNUM >= 0x1240
|
||||
|
|
@ -146,11 +133,6 @@
|
|||
/* Is it safe to copy? */
|
||||
#define SAFE_TO_COPY(chunk) (((chunk) & PNG_U32(0,0,0,32)) != 0)
|
||||
|
||||
/* Fix ups for builds with limited read support */
|
||||
#ifndef PNG_ERROR_TEXT_SUPPORTED
|
||||
# define png_error(a,b) png_err(a)
|
||||
#endif
|
||||
|
||||
/********************************* UTILITIES **********************************/
|
||||
/* UNREACHED is a value to cause an assert to fail. Because of the way the
|
||||
* assert macro is written the string "UNREACHED" is produced in the error
|
||||
|
|
@ -218,7 +200,7 @@ uarb_inc(uarb num, int in_digits, png_int_32 add)
|
|||
* in_digits+1 if add is known to be in the range -65535..65535.
|
||||
*/
|
||||
{
|
||||
FIX_GCC int out_digits = 0;
|
||||
int out_digits = 0;
|
||||
|
||||
while (out_digits < in_digits)
|
||||
{
|
||||
|
|
@ -263,7 +245,7 @@ uarb_add32(uarb num, int in_digits, png_uint_32 add)
|
|||
}
|
||||
|
||||
static int
|
||||
uarb_mult_digit(uarb acc, int a_digits, uarb num, FIX_GCC int n_digits,
|
||||
uarb_mult_digit(uarb acc, int a_digits, uarb num, int n_digits,
|
||||
png_uint_16 val)
|
||||
/* Primitive one-digit multiply - 'val' must be 0..65535. Note that this
|
||||
* primitive is a multiply and accumulate - the result of *num * val is added
|
||||
|
|
@ -336,7 +318,7 @@ uarb_shift(uarb inout, int ndigits, unsigned int right_shift)
|
|||
* 1..15
|
||||
*/
|
||||
{
|
||||
FIX_GCC int i = ndigits;
|
||||
int i = ndigits;
|
||||
png_uint_16 carry = 0;
|
||||
|
||||
assert(right_shift >= 1 && right_shift <= 15);
|
||||
|
|
@ -351,7 +333,7 @@ uarb_shift(uarb inout, int ndigits, unsigned int right_shift)
|
|||
inout[i] = temp;
|
||||
|
||||
/* The shift may reduce ndigits */
|
||||
if (i == ndigits-1 && temp == 0)
|
||||
if (i+1 == ndigits && temp == 0)
|
||||
ndigits = i;
|
||||
}
|
||||
|
||||
|
|
@ -867,7 +849,7 @@ struct file
|
|||
* signature (in length,type).
|
||||
*
|
||||
* When a chunk control structure is instantiated these values are copied
|
||||
* into the structure and can then be overritten with the data for the next
|
||||
* into the structure and can then be overwritten with the data for the next
|
||||
* chunk.
|
||||
*/
|
||||
fpos_t data_pos; /* Position of first byte of chunk data */
|
||||
|
|
@ -1005,10 +987,18 @@ file_end(struct file *file)
|
|||
|
||||
if (file->out != NULL)
|
||||
{
|
||||
/* NOTE: this is bitwise |, all the following functions must execute and
|
||||
* must succeed.
|
||||
/* On some systems 'fclose' deletes the FILE struct (making it
|
||||
* inaccessbile). There is no guarantee that fclose returns an error
|
||||
* code from fflush or, indeed, from the FILE error indicator. There is
|
||||
* also no explicit (or clear) guarantee in the standard that anything
|
||||
* other than a read or write operation sets the error indicator; fflush
|
||||
* is not a read or write operation, so both conditions must be checked
|
||||
* to ensure the close succeeded and in ANSI-C conformant code they must
|
||||
* be checked before the fclose call.
|
||||
*/
|
||||
if (ferror(file->out) | fflush(file->out) | fclose(file->out))
|
||||
const int err = fflush(file->out) || ferror(file->out);
|
||||
|
||||
if (fclose(file->out) || err)
|
||||
{
|
||||
perror(file->out_name);
|
||||
emit_error(file, READ_ERROR_CODE, "output write error");
|
||||
|
|
@ -1598,7 +1588,7 @@ chunk_init(struct chunk * const chunk, struct file * const file)
|
|||
chunk->chunk_length = file->length;
|
||||
chunk->chunk_type = file->type;
|
||||
|
||||
/* Compresssed/uncompressed size information (from the zlib control structure
|
||||
/* Compressed/uncompressed size information (from the zlib control structure
|
||||
* that is used to check the compressed data in a chunk.)
|
||||
*/
|
||||
chunk->uncompressed_digits = 0;
|
||||
|
|
@ -2929,7 +2919,7 @@ process_chunk(struct file *file, png_uint_32 file_crc, png_uint_32 next_length,
|
|||
}
|
||||
|
||||
/* Control reaches this point if the chunk must be skipped. For chunks other
|
||||
* than IDAT this means that the zlib compressed data is fatally damanged and
|
||||
* than IDAT this means that the zlib compressed data is fatally damaged and
|
||||
* the chunk will not be passed to libpng. For IDAT it means that the end of
|
||||
* the IDAT stream has not yet been reached and we must handle the next
|
||||
* (IDAT) chunk. If the LZ data in an IDAT stream cannot be read 'stop' must
|
||||
|
|
@ -3961,6 +3951,14 @@ main(int argc, const char **argv)
|
|||
{
|
||||
size_t outlen = strlen(*argv);
|
||||
|
||||
if (outlen > FILENAME_MAX)
|
||||
{
|
||||
fprintf(stderr, "%s: output file name too long: %s%s%s\n",
|
||||
prog, prefix, *argv, suffix ? suffix : "");
|
||||
global.status_code |= WRITE_ERROR;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (outfile == NULL) /* else this takes precedence */
|
||||
{
|
||||
/* Consider the prefix/suffix options */
|
||||
|
|
@ -4046,4 +4044,4 @@ main(void)
|
|||
return 77;
|
||||
}
|
||||
#endif /* PNG_SETJMP_SUPPORTED */
|
||||
|
||||
/* vi: set textwidth=80 shiftwidth=3 softtabstop=-1 expandtab: */
|
||||
|
|
|
|||
|
|
@ -1,25 +0,0 @@
|
|||
#!/bin/sh
|
||||
|
||||
# reindent a libpng C source
|
||||
|
||||
# COPYRIGHT: Written by Glenn Randers-Pehrson, 2016.
|
||||
# To the extent possible under law, the author has waived all copyright and
|
||||
# related or neighboring rights to this work. This work is published from:
|
||||
# United States.
|
||||
|
||||
# Usage:
|
||||
# reindent inputtabsize outputtabsize inputcontinuestring outputcontinuestring
|
||||
#
|
||||
# Assumes that continued lines begin with indentation plus one space, and
|
||||
# that continued comments begin with indentation plus " *".
|
||||
#
|
||||
# eg, to change libpng coding style from 3-space indentation with 4-space
|
||||
# continuations to 4-space indentation with 2-space continuations:
|
||||
#
|
||||
# reindent 3 4 "\t " " " < example.c > example.c_4_2
|
||||
# and to restore the file back to libpng coding style
|
||||
# reindent 4 3 " " " " < example.c_4_2 > example.c_3_4
|
||||
|
||||
unexpand --first-only --t $1 | \
|
||||
sed -e "/^ *$3[^\*]/{s/$3/$4/}" | \
|
||||
expand -t $2
|
||||
|
|
@ -1,7 +1,4 @@
|
|||
/*-
|
||||
* sRGB.h
|
||||
*
|
||||
* Last changed in libpng 1.6.0 [February 14, 2013]
|
||||
/* sRGB.h
|
||||
*
|
||||
* COPYRIGHT: Written by John Cunningham Bowler, 2013.
|
||||
* To the extent possible under law, the author has waived all copyright and
|
||||
|
|
@ -16,6 +13,7 @@
|
|||
* (in fact the source of the numbers is the wikipedia article at
|
||||
* https://en.wikipedia.org/wiki/SRGB).
|
||||
*/
|
||||
|
||||
static double
|
||||
sRGB_from_linear(double l)
|
||||
{
|
||||
|
|
|
|||
23
Engine/lib/lpng/contrib/visupng/.editorconfig
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
# https://editorconfig.org
|
||||
|
||||
root = true
|
||||
|
||||
[*]
|
||||
charset = utf-8
|
||||
end_of_line = unset
|
||||
indent_size = 4
|
||||
indent_style = space
|
||||
insert_final_newline = true
|
||||
max_doc_length = 80
|
||||
max_line_length = 100
|
||||
trim_trailing_whitespace = true
|
||||
|
||||
[*.rc]
|
||||
end_of_line = crlf
|
||||
trim_trailing_whitespace = unset
|
||||
|
||||
[*.ds[pw]]
|
||||
end_of_line = crlf
|
||||
max_doc_length = unset
|
||||
max_line_length = unset
|
||||
trim_trailing_whitespace = unset
|
||||
|
|
@ -103,7 +103,7 @@ int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* if filename given on commandline, store it */
|
||||
/* if filename given on command line, store it */
|
||||
if ((szCmdLine != NULL) && (*szCmdLine != '\0'))
|
||||
if (szCmdLine[0] == '"')
|
||||
strncpy (szCmdFileName, szCmdLine + 1, strlen(szCmdLine) - 2);
|
||||
|
|
|
|||