diff options
Diffstat (limited to 'ff2png.c')
-rw-r--r-- | ff2png.c | 47 |
1 files changed, 46 insertions, 1 deletions
@@ -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; } |