mirror of
https://git.code.sf.net/p/libpng/code.git
synced 2025-07-10 18:04:09 +02:00

Add contrib/examples/.clang-format, tailored to fit the existing code as closely as possible. The end goal is to set up automatic formatting for the entire libpng source tree. We're doing this experiment in this subdirectory, for now. Also make refactoring changes, as follows: * Rewrite the preprocessor checks `#if PNG_FOO_SUPPORTED` to stop compilation immediately, with a descriptive `#error` about what needs to be supported. * Rewrite and reflow comments, add braces and brackets, and make other minor modifications that are suited for the clang-format'ed code.
190 lines
4.7 KiB
C
190 lines
4.7 KiB
C
/*- iccfrompng
|
|
*
|
|
* COPYRIGHT: Written by John Cunningham Bowler, 2011.
|
|
* 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.
|
|
*
|
|
* Extract any icc profiles found in the given PNG files. This is a simple
|
|
* example of a program that extracts information from the header of a PNG file
|
|
* without processing the image. Notice that some header information may occur
|
|
* after the image data. Textual data and comments are an example; the approach
|
|
* in this file won't work reliably for such data because it only looks for the
|
|
* information in the section of the file that precedes the image data.
|
|
*
|
|
* Compile and link against libpng and zlib, plus anything else required on the
|
|
* system you use.
|
|
*
|
|
* To use supply a list of PNG files containing iCCP chunks, the chunks will be
|
|
* extracted to a similarly named file with the extension replaced by 'icc',
|
|
* which will be overwritten without warning.
|
|
*/
|
|
#include <stdlib.h>
|
|
#include <setjmp.h>
|
|
#include <string.h>
|
|
#include <stdio.h>
|
|
|
|
#include <png.h>
|
|
|
|
#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;
|
|
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, NULL, NULL, NULL);
|
|
png_infop info_ptr = NULL;
|
|
png_bytep result = NULL;
|
|
|
|
/* Initialize for error or no profile: */
|
|
*proflen = 0;
|
|
|
|
if (png_ptr == NULL)
|
|
{
|
|
fprintf(stderr, "iccfrompng: version library mismatch?\n");
|
|
return 0;
|
|
}
|
|
|
|
if (setjmp(png_jmpbuf(png_ptr)))
|
|
{
|
|
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
|
|
return 0;
|
|
}
|
|
|
|
png_init_io(png_ptr, fp);
|
|
|
|
info_ptr = png_create_info_struct(png_ptr);
|
|
if (info_ptr == NULL)
|
|
png_error(png_ptr, "OOM allocating info structure");
|
|
|
|
png_read_info(png_ptr, info_ptr);
|
|
|
|
{
|
|
png_charp name;
|
|
int compression_type;
|
|
png_bytep profile;
|
|
|
|
if (png_get_iCCP(png_ptr, info_ptr, &name, &compression_type, &profile,
|
|
proflen) & PNG_INFO_iCCP)
|
|
{
|
|
result = malloc(*proflen);
|
|
if (result != NULL)
|
|
memcpy(result, profile, *proflen);
|
|
|
|
else
|
|
png_error(png_ptr, "OOM allocating profile buffer");
|
|
}
|
|
|
|
else
|
|
result = no_profile;
|
|
}
|
|
|
|
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
|
|
return result;
|
|
}
|
|
|
|
static int
|
|
extract_one_file(const char *filename)
|
|
{
|
|
int result = 0;
|
|
FILE *fp = fopen(filename, "rb");
|
|
|
|
if (fp != NULL)
|
|
{
|
|
png_uint_32 proflen = 0;
|
|
png_bytep profile = extract(fp, &proflen);
|
|
|
|
if (profile != NULL && profile != no_profile)
|
|
{
|
|
size_t len;
|
|
char *output;
|
|
|
|
{
|
|
const char *ep = strrchr(filename, '.');
|
|
|
|
if (ep != NULL)
|
|
len = ep - filename;
|
|
|
|
else
|
|
len = strlen(filename);
|
|
}
|
|
|
|
output = malloc(len + 5);
|
|
if (output != NULL)
|
|
{
|
|
FILE *of;
|
|
|
|
memcpy(output, filename, len);
|
|
strcpy(output + len, ".icc");
|
|
|
|
of = fopen(output, "wb");
|
|
if (of != NULL)
|
|
{
|
|
if (fwrite(profile, proflen, 1, of) == 1 &&
|
|
fflush(of) == 0 &&
|
|
fclose(of) == 0)
|
|
{
|
|
if (verbose)
|
|
printf("%s -> %s\n", filename, output);
|
|
/* Success return */
|
|
result = 1;
|
|
}
|
|
|
|
else
|
|
{
|
|
fprintf(stderr, "%s: error writing profile\n", output);
|
|
if (remove(output))
|
|
fprintf(stderr, "%s: could not remove file\n", output);
|
|
}
|
|
}
|
|
|
|
else
|
|
fprintf(stderr, "%s: failed to open output file\n", output);
|
|
|
|
free(output);
|
|
}
|
|
|
|
else
|
|
fprintf(stderr, "%s: OOM allocating string!\n", filename);
|
|
|
|
free(profile);
|
|
}
|
|
|
|
else if (verbose && profile == no_profile)
|
|
printf("%s has no profile\n", filename);
|
|
}
|
|
|
|
else
|
|
fprintf(stderr, "%s: could not open file\n", filename);
|
|
|
|
if (fp != NULL)
|
|
fclose(fp);
|
|
|
|
return result;
|
|
}
|
|
|
|
int
|
|
main(int argc, char **argv)
|
|
{
|
|
int i;
|
|
int extracted = 0;
|
|
|
|
for (i = 1; i < argc; ++i)
|
|
{
|
|
if (strcmp(argv[i], "-q") == 0)
|
|
verbose = 0;
|
|
|
|
else if (extract_one_file(argv[i]))
|
|
extracted = 1;
|
|
}
|
|
|
|
/* Exit code is true if any extract succeeds */
|
|
return extracted == 0;
|
|
}
|