summaryrefslogtreecommitdiff
path: root/ff2png.c
diff options
context:
space:
mode:
Diffstat (limited to 'ff2png.c')
-rw-r--r--ff2png.c47
1 files changed, 46 insertions, 1 deletions
diff --git a/ff2png.c b/ff2png.c
index a1276d7..94a6b95 100644
--- a/ff2png.c
+++ b/ff2png.c
@@ -7,12 +7,21 @@
#include <stdlib.h>
#include <string.h>
+#include <lcms2.h>
#include <png.h>
#define HEADER "farbfeld########"
static char *argv0;
+/* ProPhoto RGB */
+static cmsCIExyYTRIPLE primaries = {
+ /* x, y, Y */
+ { 0.7347, 0.2653, 0.288040 }, /* red */
+ { 0.1596, 0.8404, 0.711874 }, /* green */
+ { 0.0366, 0.0001, 0.000086 }, /* blue */
+};
+
void
pngerr(png_structp png_struct_p, png_const_charp msg)
{
@@ -23,12 +32,17 @@ pngerr(png_structp png_struct_p, png_const_charp msg)
int
main(int argc, char *argv[])
{
+ cmsContext icc_context;
+ cmsHPROFILE out_profile;
+ cmsMLU *mlu1, *mlu2;
+ cmsToneCurve *gamma18, *out_curves[3];
png_structp png_struct_p;
png_infop png_info_p;
png_size_t png_row_len, j;
png_uint_32 width, height, i;
+ uint32_t icclen;
uint16_t tmp16, *png_row;
- uint8_t hdr[16];
+ uint8_t hdr[16], *icc;
argv0 = argv[0], argc--, argv++;
@@ -49,6 +63,32 @@ main(int argc, char *argv[])
width = ntohl(*((uint32_t *)(hdr + 8)));
height = ntohl(*((uint32_t *)(hdr + 12)));
+ /* icc profile (ProPhoto RGB) */
+ if (!(icc_context = cmsCreateContext(NULL, NULL)))
+ goto lcmserr;
+ if (!(gamma18 = cmsBuildGamma(icc_context, 1.8)))
+ goto lcmserr;
+ out_curves[0] = out_curves[1] = out_curves[2] = gamma18;
+ if (!(out_profile = cmsCreateRGBProfileTHR(icc_context, cmsD50_xyY(),
+ &primaries, out_curves)))
+ goto lcmserr;
+ cmsSetHeaderFlags(out_profile, cmsEmbeddedProfileTrue | cmsUseAnywhere);
+ cmsSetHeaderRenderingIntent(out_profile, INTENT_RELATIVE_COLORIMETRIC);
+ cmsSetDeviceClass(out_profile, cmsSigColorSpaceClass);
+ if (!(mlu1 = cmsMLUalloc(NULL, 1)) || !(mlu2 = cmsMLUalloc(NULL, 1)))
+ goto lcmserr;
+ cmsMLUsetASCII(mlu1, "en", "US", "Public Domain");
+ cmsWriteTag(out_profile, cmsSigCopyrightTag, mlu1);
+ cmsMLUsetASCII(mlu2, "en", "US", "ProPhoto RGB");
+ cmsWriteTag(out_profile, cmsSigProfileDescriptionTag, mlu2);
+ cmsWriteTag(out_profile, cmsSigDeviceModelDescTag, mlu2);
+ cmsSaveProfileToMem(out_profile, NULL, &icclen);
+ if (!(icc = malloc(icclen))) {
+ fprintf(stderr, "%s: malloc: out of memory\n", argv0);
+ return 1;
+ }
+ cmsSaveProfileToMem(out_profile, icc, &icclen);
+
/* load png */
png_struct_p = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL,
pngerr, NULL);
@@ -62,6 +102,7 @@ main(int argc, char *argv[])
png_set_IHDR(png_struct_p, png_info_p, width, height, 16,
PNG_COLOR_TYPE_RGB_ALPHA, PNG_INTERLACE_NONE,
PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
+ png_set_iCCP(png_struct_p, png_info_p, "ProPhoto RGB", 0, icc, icclen);
png_write_info(png_struct_p, png_info_p);
/* write rows */
@@ -84,4 +125,8 @@ main(int argc, char *argv[])
png_destroy_write_struct(&png_struct_p, NULL);
return 0;
+lcmserr:
+ fprintf(stderr, "%s: lcms error\n", argv0);
+
+ return 1;
}