mirror of
https://git.code.sf.net/p/libpng/code.git
synced 2025-07-10 18:04:09 +02:00
Compare commits
2 Commits
0cc6436ef5
...
3bca02e274
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3bca02e274 | ||
|
|
197bbfe0d5 |
143
contrib/examples/.clang-format
Normal file
143
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
|
||||||
|
...
|
||||||
@ -26,8 +26,9 @@
|
|||||||
|
|
||||||
#include <png.h>
|
#include <png.h>
|
||||||
|
|
||||||
#if defined(PNG_READ_SUPPORTED) && defined(PNG_STDIO_SUPPORTED) && \
|
#if !defined(PNG_iCCP_SUPPORTED) || !defined(PNG_READ_SUPPORTED)
|
||||||
defined (PNG_iCCP_SUPPORTED)
|
#error This program requires libpng supporting the iCCP chunk and the read API
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
static int verbose = 1;
|
static int verbose = 1;
|
||||||
@ -36,7 +37,8 @@ static png_byte no_profile[] = "no profile";
|
|||||||
static png_bytep
|
static png_bytep
|
||||||
extract(FILE *fp, png_uint_32 *proflen)
|
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_infop info_ptr = NULL;
|
||||||
png_bytep result = NULL;
|
png_bytep result = NULL;
|
||||||
|
|
||||||
@ -107,7 +109,7 @@ extract_one_file(const char *filename)
|
|||||||
const char *ep = strrchr(filename, '.');
|
const char *ep = strrchr(filename, '.');
|
||||||
|
|
||||||
if (ep != NULL)
|
if (ep != NULL)
|
||||||
len = ep-filename;
|
len = ep - filename;
|
||||||
|
|
||||||
else
|
else
|
||||||
len = strlen(filename);
|
len = strlen(filename);
|
||||||
@ -119,7 +121,7 @@ extract_one_file(const char *filename)
|
|||||||
FILE *of;
|
FILE *of;
|
||||||
|
|
||||||
memcpy(output, filename, len);
|
memcpy(output, filename, len);
|
||||||
strcpy(output+len, ".icc");
|
strcpy(output + len, ".icc");
|
||||||
|
|
||||||
of = fopen(output, "wb");
|
of = fopen(output, "wb");
|
||||||
if (of != NULL)
|
if (of != NULL)
|
||||||
@ -161,6 +163,9 @@ extract_one_file(const char *filename)
|
|||||||
else
|
else
|
||||||
fprintf(stderr, "%s: could not open file\n", filename);
|
fprintf(stderr, "%s: could not open file\n", filename);
|
||||||
|
|
||||||
|
if (fp != NULL)
|
||||||
|
fclose(fp);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -170,7 +175,7 @@ main(int argc, char **argv)
|
|||||||
int i;
|
int i;
|
||||||
int extracted = 0;
|
int extracted = 0;
|
||||||
|
|
||||||
for (i=1; i<argc; ++i)
|
for (i = 1; i < argc; ++i)
|
||||||
{
|
{
|
||||||
if (strcmp(argv[i], "-q") == 0)
|
if (strcmp(argv[i], "-q") == 0)
|
||||||
verbose = 0;
|
verbose = 0;
|
||||||
@ -182,4 +187,3 @@ main(int argc, char **argv)
|
|||||||
/* Exit code is true if any extract succeeds */
|
/* Exit code is true if any extract succeeds */
|
||||||
return extracted == 0;
|
return extracted == 0;
|
||||||
}
|
}
|
||||||
#endif /* READ && STDIO && iCCP */
|
|
||||||
|
|||||||
@ -15,8 +15,8 @@
|
|||||||
* images. Normally you would call png_set_interlace_handling() to have libpng
|
* 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
|
* deal with the interlace for you, but that obliges you to buffer half of the
|
||||||
* image to assemble the interlaced rows. In this code
|
* image to assemble the interlaced rows. In this code
|
||||||
* png_set_interlace_handling() is not called and, instead, the code handles the
|
* png_set_interlace_handling() is not called and, instead, the code handles
|
||||||
* interlace passes directly looking for the required pixel.
|
* the interlace passes directly looking for the required pixel.
|
||||||
*/
|
*/
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@ -27,34 +27,37 @@
|
|||||||
*/
|
*/
|
||||||
#include "../../png.h"
|
#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. */
|
/* Return component 'c' of pixel 'x' from the given row. */
|
||||||
static unsigned int
|
static unsigned int
|
||||||
component(png_const_bytep row, png_uint_32 x, unsigned int c,
|
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
|
/* 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
|
* 2^37 bits wide (for a 64-bit pixel - the largest possible) and hence
|
||||||
* bytes wide. Since the row fitted into memory, however, the following must
|
* 2^34 bytes wide. Since the row fitted into memory, the following must
|
||||||
* work:
|
* work:
|
||||||
*/
|
*/
|
||||||
png_uint_32 bit_offset_hi = bit_depth * ((x >> 6) * channels);
|
png_uint_32 bit_offset_hi = bit_depth * ((x >> 6) * channels);
|
||||||
png_uint_32 bit_offset_lo = bit_depth * ((x & 0x3f) * channels + c);
|
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;
|
row += bit_offset_lo >> 3;
|
||||||
bit_offset_lo &= 0x07;
|
bit_offset_lo &= 0x07;
|
||||||
|
|
||||||
/* PNG pixels are packed into bytes to put the first pixel in the highest
|
/* 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
|
* bits of the byte, and into two bytes for 16-bit values with the high
|
||||||
* first, so:
|
* 8 bits first, so:
|
||||||
*/
|
*/
|
||||||
switch (bit_depth)
|
switch (bit_depth)
|
||||||
{
|
{
|
||||||
case 1: return (row[0] >> (7-bit_offset_lo)) & 0x01;
|
case 1: return (row[0] >> (7 - bit_offset_lo)) & 0x01;
|
||||||
case 2: return (row[0] >> (6-bit_offset_lo)) & 0x03;
|
case 2: return (row[0] >> (6 - bit_offset_lo)) & 0x03;
|
||||||
case 4: return (row[0] >> (4-bit_offset_lo)) & 0x0f;
|
case 4: return (row[0] >> (4 - bit_offset_lo)) & 0x0f;
|
||||||
case 8: return row[0];
|
case 8: return row[0];
|
||||||
case 16: return (row[0] << 8) + row[1];
|
case 16: return (row[0] << 8) + row[1];
|
||||||
default:
|
default:
|
||||||
@ -92,22 +95,24 @@ print_pixel(png_structp png_ptr, png_infop info_ptr, png_const_bytep row,
|
|||||||
int num_palette = 0;
|
int num_palette = 0;
|
||||||
|
|
||||||
if ((png_get_PLTE(png_ptr, info_ptr, &palette, &num_palette) &
|
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;
|
png_bytep trans_alpha = NULL;
|
||||||
int num_trans = 0;
|
int num_trans = 0;
|
||||||
if ((png_get_tRNS(png_ptr, info_ptr, &trans_alpha, &num_trans,
|
if ((png_get_tRNS(png_ptr, info_ptr, &trans_alpha, &num_trans,
|
||||||
NULL) & PNG_INFO_tRNS) && num_trans > 0 &&
|
NULL) & PNG_INFO_tRNS) &&
|
||||||
trans_alpha != NULL)
|
(num_trans > 0) &&
|
||||||
|
(trans_alpha != NULL))
|
||||||
printf("INDEXED %u = %d %d %d %d\n", index,
|
printf("INDEXED %u = %d %d %d %d\n", index,
|
||||||
palette[index].red, palette[index].green,
|
palette[index].red, palette[index].green,
|
||||||
palette[index].blue,
|
palette[index].blue,
|
||||||
index < num_trans ? trans_alpha[index] : 255);
|
index < num_trans ? trans_alpha[index] : 255);
|
||||||
|
|
||||||
else /* no transparency */
|
else /* no transparency */
|
||||||
printf("INDEXED %u = %d %d %d\n", index,
|
printf("INDEXED %u = %d %d %d\n", index, palette[index].red,
|
||||||
palette[index].red, palette[index].green,
|
palette[index].green, palette[index].blue);
|
||||||
palette[index].blue);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
else
|
else
|
||||||
@ -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
|
/* This program uses the default, <setjmp.h> based, libpng error handling
|
||||||
* mechanism, therefore any local variable that exists before the call to
|
* 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
|
* be declared with 'volatile' to ensure that their values don't get
|
||||||
* destroyed by longjmp:
|
* destroyed by longjmp:
|
||||||
*/
|
*/
|
||||||
volatile int result = 1/*fail*/;
|
volatile int result = 1 /*fail*/;
|
||||||
|
|
||||||
if (argc == 4)
|
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
|
* writes error messages to stderr. Creating the png_struct is a
|
||||||
* little tricky; just copy the following code.
|
* little tricky; just copy the following code.
|
||||||
*/
|
*/
|
||||||
png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,
|
png_structp png_ptr =
|
||||||
NULL, NULL, NULL);
|
png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
|
||||||
|
|
||||||
if (png_ptr != NULL)
|
if (png_ptr != NULL)
|
||||||
{
|
{
|
||||||
@ -202,16 +208,16 @@ int main(int argc, const char **argv)
|
|||||||
* space. In this case png_malloc is used - it will not
|
* space. In this case png_malloc is used - it will not
|
||||||
* return if memory isn't available.
|
* return if memory isn't available.
|
||||||
*/
|
*/
|
||||||
row = png_malloc(png_ptr, png_get_rowbytes(png_ptr,
|
row =
|
||||||
info_ptr));
|
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.
|
* to a local here - just use row for the png_free below.
|
||||||
*/
|
*/
|
||||||
row_tmp = row;
|
row_tmp = row;
|
||||||
|
|
||||||
/* All the information we need is in the header is returned by
|
/* All the information we need is in the header returned by
|
||||||
* png_get_IHDR, if this fails we can now use 'png_error' to
|
* png_get_IHDR. If this fails, we can use 'png_error' to
|
||||||
* signal the error and return control to the setjmp above.
|
* signal the error and return control to the setjmp above.
|
||||||
*/
|
*/
|
||||||
if (png_get_IHDR(png_ptr, info_ptr, &width, &height,
|
if (png_get_IHDR(png_ptr, info_ptr, &width, &height,
|
||||||
@ -242,7 +248,7 @@ int main(int argc, const char **argv)
|
|||||||
/* Now read the pixels, pass-by-pass, row-by-row: */
|
/* Now read the pixels, pass-by-pass, row-by-row: */
|
||||||
png_start_read_image(png_ptr);
|
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 ystart, xstart, ystep, xstep;
|
||||||
png_uint_32 py;
|
png_uint_32 py;
|
||||||
@ -299,19 +305,27 @@ int main(int argc, const char **argv)
|
|||||||
* are, of course, much better ways of doing this
|
* are, of course, much better ways of doing this
|
||||||
* than using a for loop:
|
* than using a for loop:
|
||||||
*/
|
*/
|
||||||
if (y == py) for (px = xstart, ppx = 0;
|
if (y == py)
|
||||||
px < width; px += xstep, ++ppx) if (x == px)
|
|
||||||
{
|
{
|
||||||
/* 'ppx' is the index of the pixel in the row
|
for (px = xstart, ppx = 0;
|
||||||
* buffer.
|
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);
|
print_pixel(png_ptr, info_ptr, row_tmp,
|
||||||
|
ppx);
|
||||||
|
|
||||||
/* Now terminate the loops early - we have
|
/* Now terminate the loops early - we have
|
||||||
* found and handled the required data.
|
* found and handled the required data.
|
||||||
*/
|
*/
|
||||||
goto pass_loop_end;
|
goto pass_loop_end;
|
||||||
} /* x loop */
|
} /* x loop */
|
||||||
|
}
|
||||||
|
}
|
||||||
} /* y loop */
|
} /* y loop */
|
||||||
} /* pass loop */
|
} /* pass loop */
|
||||||
|
|
||||||
@ -323,7 +337,6 @@ int main(int argc, const char **argv)
|
|||||||
|
|
||||||
else
|
else
|
||||||
png_error(png_ptr, "pngpixel: png_get_IHDR failed");
|
png_error(png_ptr, "pngpixel: png_get_IHDR failed");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
else
|
else
|
||||||
@ -349,7 +362,8 @@ int main(int argc, const char **argv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
else
|
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);
|
png_destroy_read_struct(&png_ptr, NULL, NULL);
|
||||||
}
|
}
|
||||||
@ -368,4 +382,3 @@ int main(int argc, const char **argv)
|
|||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
#endif /* READ && SEQUENTIAL_READ */
|
|
||||||
|
|||||||
@ -8,8 +8,8 @@
|
|||||||
* Read a PNG and write it out in a fixed format, using the 'simplified API'
|
* Read a PNG and write it out in a fixed format, using the 'simplified API'
|
||||||
* that was introduced in libpng-1.6.0.
|
* that was introduced in libpng-1.6.0.
|
||||||
*
|
*
|
||||||
* This sample code is just the code from the top of 'example.c' with some error
|
* This sample code is just the code from 'example.c' with some error handling
|
||||||
* handling added. See example.c for more comments.
|
* added. See example.c in the top-level libpng directory for more comments.
|
||||||
*/
|
*/
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
@ -20,10 +20,15 @@
|
|||||||
* ensure the code picks up the local libpng implementation:
|
* ensure the code picks up the local libpng implementation:
|
||||||
*/
|
*/
|
||||||
#include "../../png.h"
|
#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;
|
int result = 1;
|
||||||
|
|
||||||
@ -48,12 +53,12 @@ int main(int argc, const char **argv)
|
|||||||
|
|
||||||
if (buffer != NULL)
|
if (buffer != NULL)
|
||||||
{
|
{
|
||||||
if (png_image_finish_read(&image, NULL/*background*/, buffer,
|
if (png_image_finish_read(&image, NULL /*background*/, buffer,
|
||||||
0/*row_stride*/, NULL/*colormap for PNG_FORMAT_FLAG_COLORMAP */))
|
0 /*row_stride*/, NULL /*colormap */))
|
||||||
{
|
{
|
||||||
if (png_image_write_to_file(&image, argv[2],
|
if (png_image_write_to_file(
|
||||||
0/*convert_to_8bit*/, buffer, 0/*row_stride*/,
|
&image, argv[2], 0 /*convert_to_8bit*/, buffer,
|
||||||
NULL/*colormap*/))
|
0 /*row_stride*/, NULL /*colormap*/))
|
||||||
result = 0;
|
result = 0;
|
||||||
|
|
||||||
else
|
else
|
||||||
@ -93,4 +98,3 @@ int main(int argc, const char **argv)
|
|||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
#endif /* READ && WRITE */
|
|
||||||
|
|||||||
@ -6,9 +6,9 @@
|
|||||||
* United States.
|
* United States.
|
||||||
*
|
*
|
||||||
* Read several PNG files, which should have an alpha channel or transparency
|
* 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
|
* information, and composite them together to produce one or more 16-bit
|
||||||
* RGBA intermediates. This involves doing the correct 'over' composition to
|
* linear RGBA intermediates. This involves doing the 'over' compositing
|
||||||
* combine the alpha channels and corresponding data.
|
* operation to combine the alpha channels and corresponding data.
|
||||||
*
|
*
|
||||||
* Finally read an output (background) PNG using the 24-bit RGB format (the
|
* 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
|
* 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
|
* 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
|
* 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,
|
* 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
|
* be regarded as being layered one on top of the other with the first
|
||||||
* on the command line) being at the bottom and the last on the top.
|
* (leftmost on the command line) being at the bottom and the last on the top.
|
||||||
*/
|
*/
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
@ -44,33 +44,39 @@
|
|||||||
*/
|
*/
|
||||||
#include "../../png.h"
|
#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
|
#define sprite_name_chars 15
|
||||||
struct sprite {
|
struct sprite
|
||||||
|
{
|
||||||
FILE *file;
|
FILE *file;
|
||||||
png_uint_16p buffer;
|
png_uint_16p buffer;
|
||||||
unsigned int width;
|
unsigned int width;
|
||||||
unsigned int height;
|
unsigned int height;
|
||||||
char name[sprite_name_chars+1];
|
char name[sprite_name_chars + 1];
|
||||||
};
|
};
|
||||||
|
|
||||||
#if 0 /* div by 65535 test program */
|
#if 0 /* div by 65535 test program */
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
int main(void) {
|
int
|
||||||
|
main(void)
|
||||||
|
{
|
||||||
double err = 0;
|
double err = 0;
|
||||||
unsigned int xerr = 0;
|
unsigned int xerr = 0;
|
||||||
unsigned int r = 32769;
|
unsigned int r = 32769;
|
||||||
{
|
|
||||||
unsigned int x = 0;
|
unsigned int x = 0;
|
||||||
|
|
||||||
do {
|
do
|
||||||
|
{
|
||||||
unsigned int t = x + (x >> 16) /*+ (x >> 31)*/ + r;
|
unsigned int t = x + (x >> 16) /*+ (x >> 31)*/ + r;
|
||||||
double v = x, errtest;
|
double v = x, errtest;
|
||||||
|
|
||||||
if (t < x) {
|
if (t < x)
|
||||||
|
{
|
||||||
fprintf(stderr, "overflow: %u+%u -> %u\n", x, r, t);
|
fprintf(stderr, "overflow: %u+%u -> %u\n", x, r, t);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -80,18 +86,19 @@ int main(void) {
|
|||||||
t >>= 16;
|
t >>= 16;
|
||||||
errtest -= t;
|
errtest -= t;
|
||||||
|
|
||||||
if (errtest > err) {
|
if (errtest > err)
|
||||||
|
{
|
||||||
err = errtest;
|
err = errtest;
|
||||||
xerr = x;
|
xerr = x;
|
||||||
|
|
||||||
if (errtest >= .5) {
|
if (errtest >= .5)
|
||||||
|
{
|
||||||
fprintf(stderr, "error: %u/65535 = %f, not %u, error %f\n",
|
fprintf(stderr, "error: %u/65535 = %f, not %u, error %f\n",
|
||||||
x, v, t, errtest);
|
x, v, t, errtest);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} while (++x <= 65535U*65535U);
|
} while (++x <= 65535U * 65535U);
|
||||||
}
|
|
||||||
|
|
||||||
printf("error %f @ %u\n", err, xerr);
|
printf("error %f @ %u\n", err, xerr);
|
||||||
|
|
||||||
@ -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
|
/* Check for an x or y offset that pushes any part of the image beyond the
|
||||||
* right or bottom of the sprite:
|
* right or bottom of the sprite:
|
||||||
*/
|
*/
|
||||||
if ((y_offset < 0 || (unsigned)/*SAFE*/y_offset < sprite->height) &&
|
if ((y_offset < 0 || /*SAFE*/ (unsigned)y_offset < sprite->height) &&
|
||||||
(x_offset < 0 || (unsigned)/*SAFE*/x_offset < sprite->width))
|
(x_offset < 0 || /*SAFE*/ (unsigned)x_offset < sprite->width))
|
||||||
{
|
{
|
||||||
unsigned int y = 0;
|
unsigned int y = 0;
|
||||||
|
|
||||||
@ -130,7 +137,7 @@ sprite_op(const struct sprite *sprite, int x_offset, int y_offset,
|
|||||||
do
|
do
|
||||||
{
|
{
|
||||||
/* In and out are RGBA values, so: */
|
/* 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];
|
png_uint_32 in_alpha = in_pixel[3];
|
||||||
|
|
||||||
/* This is the optimized Porter-Duff 'Over' operation, when the
|
/* 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)
|
if (in_alpha > 0)
|
||||||
{
|
{
|
||||||
png_uint_16 *out_pixel = sprite->buffer +
|
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: */
|
/* This is the weight to apply to the output: */
|
||||||
in_alpha = 65535-in_alpha;
|
in_alpha = 65535 - in_alpha;
|
||||||
|
|
||||||
if (in_alpha > 0)
|
if (in_alpha > 0)
|
||||||
{
|
{
|
||||||
@ -159,9 +166,9 @@ sprite_op(const struct sprite *sprite, int x_offset, int y_offset,
|
|||||||
*/
|
*/
|
||||||
png_uint_32 tmp;
|
png_uint_32 tmp;
|
||||||
|
|
||||||
# define compose(c)\
|
# define compose(c) \
|
||||||
tmp = out_pixel[c] * in_alpha;\
|
tmp = out_pixel[c] * in_alpha; \
|
||||||
tmp = (tmp + (tmp >> 16) + 32769) >> 16;\
|
tmp = (tmp + (tmp >> 16) + 32769) >> 16; \
|
||||||
out_pixel[c] = tmp + in_pixel[c]
|
out_pixel[c] = tmp + in_pixel[c]
|
||||||
|
|
||||||
/* The following is very vectorizable... */
|
/* The following is very vectorizable... */
|
||||||
@ -172,15 +179,15 @@ sprite_op(const struct sprite *sprite, int x_offset, int y_offset,
|
|||||||
}
|
}
|
||||||
|
|
||||||
else
|
else
|
||||||
out_pixel[0] = in_pixel[0],
|
{
|
||||||
out_pixel[1] = in_pixel[1],
|
out_pixel[0] = in_pixel[0];
|
||||||
out_pixel[2] = in_pixel[2],
|
out_pixel[1] = in_pixel[1];
|
||||||
|
out_pixel[2] = in_pixel[2];
|
||||||
out_pixel[3] = in_pixel[3];
|
out_pixel[3] = in_pixel[3];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
while (++x < image->width);
|
} while (++x < image->width);
|
||||||
}
|
} while (++y < image->height);
|
||||||
while (++y < image->height);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -224,9 +231,8 @@ create_sprite(struct sprite *sprite, int *argc, const char ***argv)
|
|||||||
|
|
||||||
if (buffer != NULL)
|
if (buffer != NULL)
|
||||||
{
|
{
|
||||||
if (png_image_finish_read(&image, NULL/*background*/, buffer,
|
if (png_image_finish_read(&image, NULL /*background*/, buffer,
|
||||||
0/*row_stride*/,
|
0 /*row_stride*/, NULL /*colormap*/))
|
||||||
NULL/*colormap for PNG_FORMAT_FLAG_COLORMAP*/))
|
|
||||||
{
|
{
|
||||||
/* This is the place where the Porter-Duff 'Over' operator
|
/* This is the place where the Porter-Duff 'Over' operator
|
||||||
* needs to be done by this code. In fact, any image
|
* needs to be done by this code. In fact, any image
|
||||||
@ -290,8 +296,9 @@ create_sprite(struct sprite *sprite, int *argc, const char ***argv)
|
|||||||
save.flags = PNG_IMAGE_FLAG_FAST;
|
save.flags = PNG_IMAGE_FLAG_FAST;
|
||||||
save.colormap_entries = 0;
|
save.colormap_entries = 0;
|
||||||
|
|
||||||
if (png_image_write_to_stdio(&save, sprite->file, 1/*convert_to_8_bit*/,
|
if (png_image_write_to_stdio(&save, sprite->file, 1 /*convert_to_8_bit*/,
|
||||||
sprite->buffer, 0/*row_stride*/, NULL/*colormap*/))
|
sprite->buffer, 0 /*row_stride*/,
|
||||||
|
NULL /*colormap*/))
|
||||||
{
|
{
|
||||||
/* Success; the buffer is no longer needed: */
|
/* Success; the buffer is no longer needed: */
|
||||||
free(sprite->buffer);
|
free(sprite->buffer);
|
||||||
@ -305,7 +312,8 @@ create_sprite(struct sprite *sprite, int *argc, const char ***argv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
else
|
else
|
||||||
fprintf(stderr, "simpleover: sprite %s: could not allocate tmpfile: %s\n",
|
fprintf(stderr,
|
||||||
|
"simpleover: sprite %s: could not allocate tmpfile: %s\n",
|
||||||
sprite->name, strerror(errno));
|
sprite->name, strerror(errno));
|
||||||
|
|
||||||
return 0; /* fail */
|
return 0; /* fail */
|
||||||
@ -334,10 +342,10 @@ add_sprite(png_imagep output, png_bytep out_buf, struct sprite *sprite,
|
|||||||
* will fit.
|
* will fit.
|
||||||
*/
|
*/
|
||||||
if (x < 0 || y < 0 ||
|
if (x < 0 || y < 0 ||
|
||||||
(unsigned)/*SAFE*/x >= output->width ||
|
/*SAFE*/ (unsigned)x >= output->width ||
|
||||||
(unsigned)/*SAFE*/y >= output->height ||
|
/*SAFE*/ (unsigned)y >= output->height ||
|
||||||
sprite->width > output->width-x ||
|
sprite->width > output->width - x ||
|
||||||
sprite->height > output->height-y)
|
sprite->height > output->height - y)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "simpleover: sprite %s @ (%d,%d) outside image\n",
|
fprintf(stderr, "simpleover: sprite %s @ (%d,%d) outside image\n",
|
||||||
sprite->name, x, y);
|
sprite->name, x, y);
|
||||||
@ -359,10 +367,10 @@ add_sprite(png_imagep output, png_bytep out_buf, struct sprite *sprite,
|
|||||||
{
|
{
|
||||||
in.format = PNG_FORMAT_RGB; /* force compose */
|
in.format = PNG_FORMAT_RGB; /* force compose */
|
||||||
|
|
||||||
if (png_image_finish_read(&in, NULL/*background*/,
|
if (png_image_finish_read(
|
||||||
out_buf + (y*output->width + x)*3/*RGB*/,
|
&in, NULL /*background*/,
|
||||||
output->width*3/*row_stride*/,
|
out_buf + (y * output->width + x) * 3 /*RGB*/,
|
||||||
NULL/*colormap for PNG_FORMAT_FLAG_COLORMAP*/))
|
output->width * 3 /*row_stride*/, NULL /*colormap*/))
|
||||||
{
|
{
|
||||||
++*argv, --*argc;
|
++*argv, --*argc;
|
||||||
continue;
|
continue;
|
||||||
@ -392,7 +400,7 @@ simpleover_process(png_imagep output, png_bytep out_buf, int argc,
|
|||||||
const char **argv)
|
const char **argv)
|
||||||
{
|
{
|
||||||
int result = 1; /* success */
|
int result = 1; /* success */
|
||||||
# define csprites 10/*limit*/
|
# define csprites 10 /*limit*/
|
||||||
# define str(a) #a
|
# define str(a) #a
|
||||||
int nsprites = 0;
|
int nsprites = 0;
|
||||||
struct sprite sprites[csprites];
|
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].width = sprites[nsprites].height = 0;
|
||||||
sprites[nsprites].name[0] = 0;
|
sprites[nsprites].name[0] = 0;
|
||||||
|
|
||||||
n = sscanf(argv[0], "--sprite=%u,%u,%" str(sprite_name_chars) "s%c",
|
n = sscanf(argv[0],
|
||||||
|
"--sprite=%u,%u,%" str(sprite_name_chars) "s%c",
|
||||||
&sprites[nsprites].width, &sprites[nsprites].height,
|
&sprites[nsprites].width, &sprites[nsprites].height,
|
||||||
sprites[nsprites].name, &tombstone);
|
sprites[nsprites].name, &tombstone);
|
||||||
|
|
||||||
if ((n == 2 || n == 3) &&
|
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;
|
size_t buf_size, tmp;
|
||||||
|
|
||||||
/* Default a name if not given. */
|
/* Default a name if not given. */
|
||||||
if (sprites[nsprites].name[0] == 0)
|
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
|
/* Allocate a buffer for the sprite and calculate the buffer
|
||||||
* size:
|
* size:
|
||||||
*/
|
*/
|
||||||
buf_size = sizeof (png_uint_16 [4]);
|
buf_size = sizeof(png_uint_16[4]);
|
||||||
buf_size *= sprites[nsprites].width;
|
buf_size *= sprites[nsprites].width;
|
||||||
buf_size *= sprites[nsprites].height;
|
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].width;
|
||||||
tmp /= sprites[nsprites].height;
|
tmp /= sprites[nsprites].height;
|
||||||
|
|
||||||
if (tmp == sizeof (png_uint_16 [4]))
|
if (tmp == sizeof(png_uint_16[4]))
|
||||||
{
|
{
|
||||||
sprites[nsprites].buffer = malloc(buf_size);
|
sprites[nsprites].buffer = malloc(buf_size);
|
||||||
/* This buffer must be initialized to transparent: */
|
/* 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;
|
sprites[nsprites].file = NULL;
|
||||||
++argv, --argc;
|
++argv, --argc;
|
||||||
|
|
||||||
if (create_sprite(sprites+nsprites++, &argc, &argv))
|
if (create_sprite(sprites + nsprites++, &argc, &argv))
|
||||||
{
|
{
|
||||||
result = 1; /* still ok */
|
result = 1; /* still ok */
|
||||||
continue;
|
continue;
|
||||||
@ -466,7 +476,8 @@ simpleover_process(png_imagep output, png_bytep out_buf, int argc,
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
fprintf(stderr, "simpleover: %s: invalid sprite (%u,%u)\n",
|
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;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -480,7 +491,7 @@ simpleover_process(png_imagep output, png_bytep out_buf, int argc,
|
|||||||
|
|
||||||
else if (strncmp(argv[0], "--add=", 6) == 0)
|
else if (strncmp(argv[0], "--add=", 6) == 0)
|
||||||
{
|
{
|
||||||
const char *name = argv[0]+6;
|
const char *name = argv[0] + 6;
|
||||||
int isprite = nsprites;
|
int isprite = nsprites;
|
||||||
|
|
||||||
++argv, --argc;
|
++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 (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 */
|
goto out; /* error in add_sprite */
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@ -498,7 +510,8 @@ simpleover_process(png_imagep output, png_bytep out_buf, int argc,
|
|||||||
|
|
||||||
if (isprite < 0) /* sprite not found */
|
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;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -526,7 +539,8 @@ out:
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, const char **argv)
|
int
|
||||||
|
main(int argc, const char **argv)
|
||||||
{
|
{
|
||||||
int result = 1; /* default to fail */
|
int result = 1; /* default to fail */
|
||||||
|
|
||||||
@ -536,7 +550,7 @@ int main(int argc, const char **argv)
|
|||||||
const char *output = NULL;
|
const char *output = NULL;
|
||||||
png_image image;
|
png_image image;
|
||||||
|
|
||||||
if (argc > 2 && argv[2][0] != '-'/*an operation*/)
|
if (argc > 2 && argv[2][0] != '-' /*an operation*/)
|
||||||
{
|
{
|
||||||
output = argv[2];
|
output = argv[2];
|
||||||
argi = 3;
|
argi = 3;
|
||||||
@ -558,7 +572,7 @@ int main(int argc, const char **argv)
|
|||||||
png_color background = {0, 0xff, 0}; /* fully saturated green */
|
png_color background = {0, 0xff, 0}; /* fully saturated green */
|
||||||
|
|
||||||
if (png_image_finish_read(&image, &background, buffer,
|
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
|
/* At this point png_image_finish_read has cleaned up the
|
||||||
* allocated data in png_image, and only the buffer needs to be
|
* 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:
|
* 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: */
|
/* Write the output: */
|
||||||
if ((output != NULL &&
|
if ((output != NULL &&
|
||||||
png_image_write_to_file(&image, output,
|
png_image_write_to_file(
|
||||||
0/*convert_to_8bit*/, buffer, 0/*row_stride*/,
|
&image, output, 0 /*convert_to_8bit*/, buffer,
|
||||||
NULL/*colormap*/)) ||
|
0 /*row_stride*/, NULL /*colormap*/)) ||
|
||||||
(output == NULL &&
|
(output == NULL &&
|
||||||
png_image_write_to_stdio(&image, stdout,
|
png_image_write_to_stdio(
|
||||||
0/*convert_to_8bit*/, buffer, 0/*row_stride*/,
|
&image, stdout, 0 /*convert_to_8bit*/, buffer,
|
||||||
NULL/*colormap*/)))
|
0 /*row_stride*/, NULL /*colormap*/)))
|
||||||
result = 0;
|
result = 0;
|
||||||
|
|
||||||
else
|
else
|
||||||
fprintf(stderr, "simpleover: write %s: %s\n",
|
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 */
|
/* else simpleover_process writes an error message */
|
||||||
@ -617,7 +633,8 @@ int main(int argc, const char **argv)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Usage message */
|
/* Usage message */
|
||||||
fprintf(stderr,
|
fprintf(
|
||||||
|
stderr,
|
||||||
"simpleover: usage: simpleover background.png [output.png]\n"
|
"simpleover: usage: simpleover background.png [output.png]\n"
|
||||||
" Output 'background.png' as a 24-bit RGB PNG file in '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"
|
" 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"
|
" --sprite=width,height,name {[--at=x,y] {sprite.png}}\n"
|
||||||
" Produce a transparent sprite of size (width,height) and with\n"
|
" Produce a transparent sprite of size (width,height) and with\n"
|
||||||
" name 'name'.\n"
|
" name 'name'.\n"
|
||||||
" For each sprite.png composite it using a Porter-Duff 'Over'\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"
|
" 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"
|
" Input PNGs will be truncated to the area of the sprite.\n"
|
||||||
"\n"
|
"\n"
|
||||||
" --add='name' {x,y}\n"
|
" --add='name' {x,y}\n"
|
||||||
" Optionally, before output, composite a sprite, 'name', which\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"
|
" offset (x,y) in the output image. Each sprite must fit\n"
|
||||||
" completely within the output image.\n"
|
" completely within the output image.\n"
|
||||||
"\n"
|
"\n"
|
||||||
@ -645,4 +662,3 @@ int main(int argc, const char **argv)
|
|||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
#endif /* SIMPLIFIED_READ */
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user