From 745c70f481dd3e93b80c79678f5f376b4bc03c73 Mon Sep 17 00:00:00 2001 From: Joe Drew Date: Fri, 3 Apr 2009 16:27:27 -0400 Subject: [PATCH] Backed out changeset 6f3c2171bbb2: Bug 481926 - Rewrite color management component. r=joe,ted sr=vlad --- config/autoconf.mk.in | 6 +- config/static-config.mk | 1 + configure.in | 18 +- content/canvas/src/Makefile.in | 1 - gfx/Makefile.in | 2 +- gfx/qcms/Makefile.in | 24 - gfx/qcms/iccread.c | 783 --------- gfx/qcms/qcms.h | 153 -- gfx/qcms/qcmsint.h | 143 -- gfx/qcms/qcmstypes.h | 43 - gfx/qcms/transform.c | 1484 ----------------- gfx/src/thebes/Makefile.in | 2 - gfx/thebes/public/gfxPlatform.h | 18 +- gfx/thebes/public/gfxPlatformGtk.h | 2 +- gfx/thebes/public/gfxPlatformMac.h | 2 +- gfx/thebes/public/gfxQtPlatform.h | 2 +- gfx/thebes/public/gfxWindowsPlatform.h | 2 +- gfx/thebes/src/Makefile.in | 3 +- gfx/thebes/src/gfxContext.cpp | 1 + gfx/thebes/src/gfxPattern.cpp | 1 + gfx/thebes/src/gfxPlatform.cpp | 97 +- gfx/thebes/src/gfxPlatformGtk.cpp | 43 +- gfx/thebes/src/gfxPlatformMac.cpp | 10 +- gfx/thebes/src/gfxQtPlatform.cpp | 4 +- gfx/thebes/src/gfxWindowsPlatform.cpp | 8 +- gfx/thebes/test/Makefile.in | 5 +- layout/base/Makefile.in | 1 - layout/mathml/Makefile.in | 1 - layout/svg/base/src/Makefile.in | 1 - modules/libpr0n/build/Makefile.in | 4 +- modules/libpr0n/decoders/gif/Makefile.in | 2 +- .../libpr0n/decoders/gif/nsGIFDecoder2.cpp | 6 +- modules/libpr0n/decoders/jpeg/Makefile.in | 2 +- .../libpr0n/decoders/jpeg/nsJPEGDecoder.cpp | 49 +- modules/libpr0n/decoders/jpeg/nsJPEGDecoder.h | 6 +- modules/libpr0n/decoders/png/Makefile.in | 2 +- modules/libpr0n/decoders/png/nsPNGDecoder.cpp | 110 +- modules/libpr0n/decoders/png/nsPNGDecoder.h | 6 +- .../reftest/pngsuite-ancillary/ccwn2c08.html | 578 ++++--- .../reftest/pngsuite-ancillary/ccwn3p08.html | 558 ++++--- toolkit/library/libxul-rules.mk | 2 +- toolkit/toolkit-makefiles.sh | 7 +- toolkit/toolkit-tiers.mk | 2 +- widget/src/build/Makefile.in | 2 +- widget/src/cocoa/Makefile.in | 4 +- widget/src/cocoa/nsCocoaWindow.mm | 6 +- widget/src/gtk2/Makefile.in | 3 +- widget/src/os2/Makefile.in | 2 +- widget/src/qt/Makefile.in | 2 +- widget/src/windows/Makefile.in | 1 - widget/src/xpwidgets/Makefile.in | 2 +- widget/src/xpwidgets/nsXPLookAndFeel.cpp | 6 +- 52 files changed, 848 insertions(+), 3375 deletions(-) delete mode 100644 gfx/qcms/Makefile.in delete mode 100644 gfx/qcms/iccread.c delete mode 100644 gfx/qcms/qcms.h delete mode 100644 gfx/qcms/qcmsint.h delete mode 100644 gfx/qcms/qcmstypes.h delete mode 100644 gfx/qcms/transform.c diff --git a/config/autoconf.mk.in b/config/autoconf.mk.in index ea482624a65..814a77479e7 100644 --- a/config/autoconf.mk.in +++ b/config/autoconf.mk.in @@ -281,7 +281,7 @@ OS_LDFLAGS = @LDFLAGS@ OS_COMPILE_CFLAGS = $(OS_CPPFLAGS) @COMPILE_CFLAGS@ OS_COMPILE_CXXFLAGS = $(OS_CPPFLAGS) @COMPILE_CXXFLAGS@ -OS_INCLUDES = $(NSPR_CFLAGS) $(JPEG_CFLAGS) $(PNG_CFLAGS) $(ZLIB_CFLAGS) +OS_INCLUDES = $(NSPR_CFLAGS) $(JPEG_CFLAGS) $(PNG_CFLAGS) $(ZLIB_CFLAGS) $(LCMS_CFLAGS) OS_LIBS = @LIBS@ ACDEFINES = @MOZ_DEFINES@ @@ -448,7 +448,9 @@ PNG_LIBS = @MOZ_PNG_LIBS@ PNG_REQUIRES = png endif -QCMS_LIBS = @QCMS_LIBS@ +LCMS_CFLAGS = @LCMS_CFLAGS@ +LCMS_LIBS = @LCMS_LIBS@ +LCMS_REQUIRES = lcms MOZ_NATIVE_SQLITE = @MOZ_NATIVE_SQLITE@ SQLITE_CFLAGS = @SQLITE_CFLAGS@ diff --git a/config/static-config.mk b/config/static-config.mk index d4331a779f7..e54feabd832 100644 --- a/config/static-config.mk +++ b/config/static-config.mk @@ -69,6 +69,7 @@ STATIC_EXTRA_LIBS += \ $(PNG_LIBS) \ $(JPEG_LIBS) \ $(ZLIB_LIBS) \ + $(LCMS_LIBS) \ $(NULL) ifdef MOZ_PSM diff --git a/configure.in b/configure.in index 98cb3ad143f..1687c7e230b 100644 --- a/configure.in +++ b/configure.in @@ -129,6 +129,7 @@ GCONF_VERSION=1.2.1 LIBGNOME_VERSION=2.0 STARTUP_NOTIFICATION_VERSION=0.8 DBUS_VERSION=0.60 +LCMS_VERSION=1.17 SQLITE_VERSION=3.6.10 LIBNOTIFY_VERSION=0.4 @@ -7646,11 +7647,22 @@ AC_SUBST(MOZ_TREE_CAIRO) AC_SUBST(MOZ_CAIRO_CFLAGS) AC_SUBST(MOZ_CAIRO_LIBS) -dnl qcms +dnl ======================================================== +dnl Check for lcms dnl ======================================================== -QCMS_LIBS='$(DEPTH)/gfx/qcms/$(LIB_PREFIX)mozqcms.$(LIB_SUFFIX)' -AC_SUBST(QCMS_LIBS) +LCMS_CFLAGS= +if test "$_WIN32_MSVC"; then + if test -z "$BUILD_STATIC_LIBS" -a -z "$MOZ_ENABLE_LIBXUL"; then + LCMS_CFLAGS=-DLCMS_DLL + fi + LCMS_LIBS='$(LIBXUL_DIST)/lib/mozlcms.lib' +else + LCMS_LIBS='-L$(LIBXUL_DIST)/bin -lmozlcms' +fi + +AC_SUBST(LCMS_CFLAGS) +AC_SUBST(LCMS_LIBS) dnl ======================================================== dnl disable xul diff --git a/content/canvas/src/Makefile.in b/content/canvas/src/Makefile.in index b2581da1df9..9f57d37654a 100644 --- a/content/canvas/src/Makefile.in +++ b/content/canvas/src/Makefile.in @@ -65,7 +65,6 @@ REQUIRES = \ imglib2 \ thebes \ view \ - qcms \ $(NULL) # XXX some platforms can't handle building diff --git a/gfx/Makefile.in b/gfx/Makefile.in index 870cabc03e4..d0eed84759f 100644 --- a/gfx/Makefile.in +++ b/gfx/Makefile.in @@ -48,7 +48,7 @@ ifdef MOZ_TREE_CAIRO DIRS = cairo endif -DIRS += thebes public idl src qcms +DIRS += thebes public idl src ifdef ENABLE_TESTS ifndef MOZ_ENABLE_LIBXUL diff --git a/gfx/qcms/Makefile.in b/gfx/qcms/Makefile.in deleted file mode 100644 index 17fb66319a0..00000000000 --- a/gfx/qcms/Makefile.in +++ /dev/null @@ -1,24 +0,0 @@ -DEPTH = ../.. -topsrcdir = @top_srcdir@ -srcdir = @srcdir@ -VPATH = @srcdir@ - -include $(DEPTH)/config/autoconf.mk - -MODULE = qcms -LIBRARY_NAME = mozqcms -LIBXUL_LIBRARY = 1 -GRE_MODULE = 1 -DIST_INSTALL = 1 - -EXPORTS = qcms.h qcmstypes.h - -CSRCS = iccread.c transform.c - -FORCE_STATIC_LIB = 1 -# This library is used by other shared libs -FORCE_USE_PIC = 1 - -include $(topsrcdir)/config/rules.mk - -CFLAGS += -DMOZ_QCMS diff --git a/gfx/qcms/iccread.c b/gfx/qcms/iccread.c deleted file mode 100644 index 0c98c84e572..00000000000 --- a/gfx/qcms/iccread.c +++ /dev/null @@ -1,783 +0,0 @@ -// qcms -// Copyright (C) 2009 Mozilla Foundation -// Copyright (C) 1998-2007 Marti Maria -// -// 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. - -#include -#include -#include -#include "qcmsint.h" - -//XXX: use a better typename -typedef uint32_t __be32; -typedef uint16_t __be16; - -/* all of the platforms that we use _MSC_VER on are little endian - * so this is sufficient for now */ -#ifdef _MSC_VER -#define LITTLE_ENDIAN -#endif - -#if !defined(BIG_ENDIAN) && !defined(LITTLE_ENDIAN) -#error Unknown endianess -#endif - -#if 0 -not used yet -/* __builtin_bswap isn't available in older gccs - * so open code it for now */ -static __be32 cpu_to_be32(int32_t v) -{ -#ifdef LITTLE_ENDIAN - return ((v & 0xff) << 24) | ((v & 0xff00) << 8) | ((v & 0xff0000) >> 8) | ((v & 0xff000000) >> 24); - //return __builtin_bswap32(v); - return v; -#endif -} -#endif - -static uint32_t be32_to_cpu(__be32 v) -{ -#ifdef LITTLE_ENDIAN - return ((v & 0xff) << 24) | ((v & 0xff00) << 8) | ((v & 0xff0000) >> 8) | ((v & 0xff000000) >> 24); - //return __builtin_bswap32(v); -#else - return v; -#endif -} - -static uint32_t be16_to_cpu(__be16 v) -{ -#ifdef LITTLE_ENDIAN - return ((v & 0xff) << 8) | ((v & 0xff00) >> 8); -#else - return v; -#endif -} - -/* a wrapper around the memory that we are going to parse - * into a qcms_profile */ -struct mem_source -{ - const unsigned char *buf; - size_t size; - qcms_bool valid; - const char *invalid_reason; -}; - -static void invalid_source(struct mem_source *mem, const char *reason) -{ - mem->valid = false; - mem->invalid_reason = reason; -} - -static uint32_t read_u32(struct mem_source *mem, size_t offset) -{ - if (offset + 4 > mem->size) { - invalid_source(mem, "Invalid offset"); - return 0; - } else { - return be32_to_cpu(*(__be32*)(mem->buf + offset)); - } -} - -static uint16_t read_u16(struct mem_source *mem, size_t offset) -{ - if (offset + 2 > mem->size) { - invalid_source(mem, "Invalid offset"); - return 0; - } else { - return be16_to_cpu(*(__be16*)(mem->buf + offset)); - } -} - -static uint8_t read_u8(struct mem_source *mem, size_t offset) -{ - if (offset + 1 > mem->size) { - invalid_source(mem, "Invalid offset"); - return 0; - } else { - return *(uint8_t*)(mem->buf + offset); - } -} - -static s15Fixed16Number read_s15Fixed16Number(struct mem_source *mem, size_t offset) -{ - return read_u32(mem, offset); -} - -#if 0 -static uInt16Number read_uInt16Number(struct mem_source *mem, size_t offset) -{ - return read_u16(mem, offset); -} -#endif - -#define BAD_VALUE_PROFILE NULL -#define INVALID_PROFILE NULL -#define NO_MEM_PROFILE NULL - -/* An arbitrary 4MB limit on profile size */ -#define MAX_PROFILE_SIZE 1024*1024*4 -#define MAX_TAG_COUNT 1024 - -static void check_CMM_type_signature(struct mem_source *src) -{ - //uint32_t CMM_type_signature = read_u32(src, 4); - //TODO: do the check? - -} - -static void check_profile_version(struct mem_source *src) -{ - uint8_t major_revision = read_u8(src, 8 + 0); - uint8_t minor_revision = read_u8(src, 8 + 1); - uint8_t reserved1 = read_u8(src, 8 + 2); - uint8_t reserved2 = read_u8(src, 8 + 3); - if (major_revision > 0x2) - invalid_source(src, "Unsupported major revision"); - if (minor_revision > 0x40) - invalid_source(src, "Unsupported minor revision"); - if (reserved1 != 0 || reserved2 != 0) - invalid_source(src, "Invalid reserved bytes"); -} - -#define INPUT_DEVICE_PROFILE 0x73636e72 // 'scnr' -#define DISPLAY_DEVICE_PROFILE 0x6d6e7472 // 'mntr' -#define OUTPUT_DEVICE_PROFILE 0x70727472 // 'prtr' -#define DEVICE_LINK_PROFILE 0x6c696e6b // 'link' -#define COLOR_SPACE_PROFILE 0x73706163 // 'spac' -#define ABSTRACT_PROFILE 0x61627374 // 'abst' -#define NAMED_COLOR_PROFILE 0x6e6d636c // 'nmcl' - -static void read_class_signature(qcms_profile *profile, struct mem_source *mem) -{ - profile->class = read_u32(mem, 12); - switch (profile->class) { - case DISPLAY_DEVICE_PROFILE: - case INPUT_DEVICE_PROFILE: - break; - case OUTPUT_DEVICE_PROFILE: - default: - invalid_source(mem, "Invalid Profile/Device Class signature"); - } -} - -static void read_color_space(qcms_profile *profile, struct mem_source *mem) -{ - profile->color_space = read_u32(mem, 16); - switch (profile->color_space) { - case RGB_SIGNATURE: - case GRAY_SIGNATURE: - break; - default: - invalid_source(mem, "Unsupported colorspace"); - } -} - -struct tag -{ - uint32_t signature; - uint32_t offset; - uint32_t size; -}; - -struct tag_index { - uint32_t count; - struct tag *tags; -}; - -static struct tag_index read_tag_table(qcms_profile *profile, struct mem_source *mem) -{ - struct tag_index index = {0, NULL}; - int i; - - index.count = read_u32(mem, 128); - if (index.count > MAX_TAG_COUNT) { - invalid_source(mem, "max number of tags exceeded"); - return index; - } - - index.tags = malloc(sizeof(struct tag)*index.count); - if (index.tags) { - for (i = 0; i < index.count; i++) { - index.tags[i].signature = read_u32(mem, 128 + 4 + 4*i*3); - index.tags[i].offset = read_u32(mem, 128 + 4 + 4*i*3 + 4); - index.tags[i].size = read_u32(mem, 128 + 4 + 4*i*3 + 8); - } - } - - return index; -} - -// Checks a profile for obvious inconsistencies and returns -// true if the profile looks bogus and should probably be -// ignored. -qcms_bool qcms_profile_is_bogus(qcms_profile *profile) -{ - float sum[3], target[3], tolerance[3]; - unsigned i; - - // Sum the values - sum[0] = s15Fixed16Number_to_float(profile->redColorant.X) + - s15Fixed16Number_to_float(profile->greenColorant.X) + - s15Fixed16Number_to_float(profile->blueColorant.X); - sum[1] = s15Fixed16Number_to_float(profile->redColorant.Y) + - s15Fixed16Number_to_float(profile->greenColorant.Y) + - s15Fixed16Number_to_float(profile->blueColorant.Y); - sum[2] = s15Fixed16Number_to_float(profile->redColorant.Z) + - s15Fixed16Number_to_float(profile->greenColorant.Z) + - s15Fixed16Number_to_float(profile->blueColorant.Z); - - // Build our target vector (see mozilla bug 460629) - target[0] = 0.96420; - target[1] = 1.00000; - target[2] = 0.82491; - - // Our tolerance vector - Recommended by Chris Murphy based on - // conversion from the LAB space criterion of no more than 3 in any one - // channel. This is similar to, but slightly more tolerant than Adobe's - // criterion. - tolerance[0] = 0.02; - tolerance[1] = 0.02; - tolerance[2] = 0.04; - - // Compare with our tolerance - for (i = 0; i < 3; ++i) { - if (!(((sum[i] - tolerance[i]) <= target[i]) && - ((sum[i] + tolerance[i]) >= target[i]))) - return true; - } - - // All Good - return false; -} - -#define TAG_bXYZ 0x6258595a -#define TAG_gXYZ 0x6758595a -#define TAG_rXYZ 0x7258595a -#define TAG_rTRC 0x72545243 -#define TAG_bTRC 0x62545243 -#define TAG_gTRC 0x67545243 -#define TAG_kTRC 0x6b545243 -#define TAG_A2B0 0x41324230 - -static struct tag *find_tag(struct tag_index index, uint32_t tag_id) -{ - int i; - struct tag *tag = NULL; - for (i = 0; i < index.count; i++) { - if (index.tags[i].signature == tag_id) { - return &index.tags[i]; - } - } - return tag; -} - -#define XYZ_TYPE 0x58595a20 // 'XYZ ' -#define CURVE_TYPE 0x63757276 // 'curv' -#define LUT16_TYPE 0x6d667432 // 'mft2' -#define LUT8_TYPE 0x6d667431 // 'mft1' - -static struct XYZNumber read_tag_XYZType(struct mem_source *src, struct tag_index index, uint32_t tag_id) -{ - struct XYZNumber num = {0}; - struct tag *tag = find_tag(index, tag_id); - if (tag) { - uint32_t offset = tag->offset; - - uint32_t type = read_u32(src, offset); - if (type != XYZ_TYPE) - invalid_source(src, "unexpected type, expected XYZ"); - num.X = read_s15Fixed16Number(src, offset+8); - num.Y = read_s15Fixed16Number(src, offset+12); - num.Z = read_s15Fixed16Number(src, offset+16); - } else { - invalid_source(src, "missing xyztag"); - } - return num; -} - -static struct curveType *read_tag_curveType(struct mem_source *src, struct tag_index index, uint32_t tag_id) -{ - struct tag *tag = find_tag(index, tag_id); - struct curveType *curve = NULL; - if (tag) { - uint32_t offset = tag->offset; - uint32_t type = read_u32(src, offset); - uint32_t count = read_u32(src, offset+8); - int i; - - if (type != CURVE_TYPE) { - invalid_source(src, "unexpected type, expected CURV"); - return NULL; - } - -#define MAX_CURVE_ENTRIES 40000 //arbitrary - if (count > MAX_CURVE_ENTRIES) { - invalid_source(src, "curve size too large"); - return NULL; - } - curve = malloc(sizeof(struct curveType) + sizeof(uInt16Number)*count); - if (!curve) - return NULL; - - curve->count = count; - for (i=0; idata[i] = read_u16(src, offset + 12 + i *2); - } - } else { - invalid_source(src, "missing curvetag"); - } - - return curve; -} - -/* This function's not done yet */ -static struct lutType *read_tag_lutType(struct mem_source *src, struct tag_index index, uint32_t tag_id) -{ - struct tag *tag = find_tag(index, tag_id); - uint32_t offset = tag->offset; - uint32_t type = read_u32(src, offset); - uint16_t num_input_table_entries; - uint16_t num_output_table_entries; - uint8_t in_chan, grid_points, out_chan; - uint32_t clut_size; - struct lutType *lut; - int i; - - num_input_table_entries = read_u16(src, offset + 48); - num_output_table_entries = read_u16(src, offset + 50); - - in_chan = read_u8(src, offset + 8); - out_chan = read_u8(src, offset + 9); - grid_points = read_u8(src, offset + 10); - - if (!src->valid) - return NULL; - - clut_size = in_chan * grid_points * out_chan; -#define MAX_CLUT_SIZE 10000 // arbitrary - if (clut_size > MAX_CLUT_SIZE) { - return NULL; - } - - if (type != LUT16_TYPE && type != LUT8_TYPE) - return NULL; - - lut = malloc(sizeof(struct lutType) + (clut_size + num_input_table_entries + num_output_table_entries)*sizeof(uint8_t)); - if (!lut) - return NULL; - lut->num_input_channels = read_u8(src, offset + 8); - lut->num_output_channels = read_u8(src, offset + 9); - lut->num_clut_grid_points = read_u8(src, offset + 10); - lut->e00 = read_s15Fixed16Number(src, offset+12); - lut->e01 = read_s15Fixed16Number(src, offset+16); - lut->e02 = read_s15Fixed16Number(src, offset+20); - lut->e10 = read_s15Fixed16Number(src, offset+24); - lut->e11 = read_s15Fixed16Number(src, offset+28); - lut->e12 = read_s15Fixed16Number(src, offset+32); - lut->e20 = read_s15Fixed16Number(src, offset+36); - lut->e21 = read_s15Fixed16Number(src, offset+40); - lut->e22 = read_s15Fixed16Number(src, offset+44); - - //TODO: finish up - for (i = 0; i < lut->num_input_table_entries; i++) { - } - return lut; -} - -static void read_rendering_intent(qcms_profile *profile, struct mem_source *src) -{ - profile->rendering_intent = read_u32(src, 64); - switch (profile->rendering_intent) { - case QCMS_INTENT_PERCEPTUAL: - case QCMS_INTENT_SATURATION: - case QCMS_INTENT_RELATIVE_COLORIMETRIC: - case QCMS_INTENT_ABSOLUTE_COLORIMETRIC: - break; - default: - invalid_source(src, "unknown rendering intent"); - } -} - -qcms_profile *qcms_profile_create(void) -{ - return calloc(sizeof(qcms_profile), 1); -} - -/* build sRGB gamma table */ -/* based on cmsBuildParametricGamma() */ -static uint16_t *build_sRGB_gamma_table(int num_entries) -{ - int i; - /* taken from lcms: Build_sRGBGamma() */ - double gamma = 2.4; - double a = 1./1.055; - double b = 0.055/1.055; - double c = 1./12.92; - double d = 0.04045; - - uint16_t *table = malloc(sizeof(uint16_t) * num_entries); - if (!table) - return NULL; - - for (i=0; i= d - // Y = cX | X < d - if (x >= d) { - double e = (a*x + b); - if (e > 0) - y = pow(e, gamma); - else - y = 0; - } else { - y = c*x; - } - - // Saturate -- this could likely move to a separate function - output = y * 65535. + .5; - if (output > 65535.) - output = 65535; - if (output < 0) - output = 0; - table[i] = (uint16_t)floor(output); - } - return table; -} - -static struct curveType *curve_from_table(uint16_t *table, int num_entries) -{ - struct curveType *curve; - int i; - curve = malloc(sizeof(struct curveType) + sizeof(uInt16Number)*num_entries); - if (!curve) - return NULL; - curve->count = num_entries; - for (i = 0; i < num_entries; i++) { - curve->data[i] = table[i]; - } - return curve; -} - -static uint16_t float_to_u8Fixed8Number(float a) -{ - if (a > (255. + 255./256)) - return 0xffff; - else if (a < 0.) - return 0; - else - return floor(a*256. + .5); -} - -static struct curveType *curve_from_gamma(float gamma) -{ - struct curveType *curve; - int num_entries = 1; - curve = malloc(sizeof(struct curveType) + sizeof(uInt16Number)*num_entries); - if (!curve) - return NULL; - curve->count = num_entries; - curve->data[0] = float_to_u8Fixed8Number(gamma); - return curve; -} - -static void qcms_profile_fini(qcms_profile *profile) -{ - free(profile->redTRC); - free(profile->blueTRC); - free(profile->greenTRC); - free(profile->grayTRC); - free(profile); -} - -//XXX: it would be nice if we had a way of ensuring -// everything in a profile was initialized regardless of how it was created - -//XXX: should this also be taking a black_point? -/* similar to CGColorSpaceCreateCalibratedRGB */ -qcms_profile* qcms_profile_create_rgb_with_gamma( - qcms_CIE_xyY white_point, - qcms_CIE_xyYTRIPLE primaries, - float gamma) -{ - qcms_profile* profile = qcms_profile_create(); - - //XXX: should store the whitepoint - set_rgb_colorants(profile, white_point, primaries); - - profile->redTRC = curve_from_gamma(gamma); - profile->blueTRC = curve_from_gamma(gamma); - profile->greenTRC = curve_from_gamma(gamma); - - if (!profile->redTRC || !profile->blueTRC || !profile->greenTRC) { - qcms_profile_fini(profile); - return NO_MEM_PROFILE; - } - profile->class = DISPLAY_DEVICE_PROFILE; - profile->rendering_intent = QCMS_INTENT_PERCEPTUAL; - profile->color_space = RGB_SIGNATURE; - return profile; -} - -qcms_profile* qcms_profile_create_rgb_with_table( - qcms_CIE_xyY white_point, - qcms_CIE_xyYTRIPLE primaries, - uint16_t *table, int num_entries) -{ - qcms_profile* profile = qcms_profile_create(); - - //XXX: should store the whitepoint - set_rgb_colorants(profile, white_point, primaries); - - profile->redTRC = curve_from_table(table, num_entries); - profile->blueTRC = curve_from_table(table, num_entries); - profile->greenTRC = curve_from_table(table, num_entries); - - if (!profile->redTRC || !profile->blueTRC || !profile->greenTRC) { - qcms_profile_fini(profile); - return NO_MEM_PROFILE; - } - profile->class = DISPLAY_DEVICE_PROFILE; - profile->rendering_intent = QCMS_INTENT_PERCEPTUAL; - profile->color_space = RGB_SIGNATURE; - return profile; -} - -/* from lcms: cmsWhitePointFromTemp */ -/* tempK must be >= 4000. and <= 25000. - * similar to argyll: icx_DTEMP2XYZ() */ -static qcms_CIE_xyY white_point_from_temp(int temp_K) -{ - qcms_CIE_xyY white_point; - double x, y; - double T, T2, T3; - // double M1, M2; - - // No optimization provided. - T = temp_K; - T2 = T*T; // Square - T3 = T2*T; // Cube - - // For correlated color temperature (T) between 4000K and 7000K: - if (T >= 4000. && T <= 7000.) { - x = -4.6070*(1E9/T3) + 2.9678*(1E6/T2) + 0.09911*(1E3/T) + 0.244063; - } else { - // or for correlated color temperature (T) between 7000K and 25000K: - if (T > 7000.0 && T <= 25000.0) { - x = -2.0064*(1E9/T3) + 1.9018*(1E6/T2) + 0.24748*(1E3/T) + 0.237040; - } else { - assert(0 && "invalid temp"); - } - } - - // Obtain y(x) - - y = -3.000*(x*x) + 2.870*x - 0.275; - - // wave factors (not used, but here for futures extensions) - - // M1 = (-1.3515 - 1.7703*x + 5.9114 *y)/(0.0241 + 0.2562*x - 0.7341*y); - // M2 = (0.0300 - 31.4424*x + 30.0717*y)/(0.0241 + 0.2562*x - 0.7341*y); - - // Fill white_point struct - white_point.x = x; - white_point.y = y; - white_point.Y = 1.0; - - return white_point; -} - -qcms_profile* qcms_profile_sRGB(void) -{ - qcms_profile *profile; - uint16_t *table; - - qcms_CIE_xyYTRIPLE Rec709Primaries = { - {0.6400, 0.3300, 1.0}, - {0.3000, 0.6000, 1.0}, - {0.1500, 0.0600, 1.0} - }; - qcms_CIE_xyY D65; - - D65 = white_point_from_temp(6504); - - table = build_sRGB_gamma_table(1024); - - if (!table) - return NO_MEM_PROFILE; - - profile = qcms_profile_create_rgb_with_table(D65, Rec709Primaries, table, 1024); - free(table); - return profile; -} - - -/* qcms_profile_from_memory does not hold a reference to the memory passed in */ -qcms_profile* qcms_profile_from_memory(const void *mem, size_t size) -{ - uint32_t length; - struct mem_source source; - struct mem_source *src = &source; - struct tag_index index; - qcms_profile *profile; - - source.buf = mem; - source.size = size; - source.valid = true; - length = read_u32(src, 0); - if (length <= size) { - // shrink the area that we can read if appropriate - source.size = length; - } else { - return INVALID_PROFILE; - } - - profile = qcms_profile_create(); - - check_CMM_type_signature(src); - check_profile_version(src); - read_class_signature(profile, src); - read_rendering_intent(profile, src); - read_color_space(profile, src); - //TODO read rest of profile stuff - - if (!src->valid) - goto invalid_profile; - - index = read_tag_table(profile, src); - if (!src->valid || !index.tags) - goto invalid_tag_table; - - if (profile->class == DISPLAY_DEVICE_PROFILE || profile->class == INPUT_DEVICE_PROFILE) { - if (profile->color_space == RGB_SIGNATURE) { - - profile->redColorant = read_tag_XYZType(src, index, TAG_rXYZ); - profile->blueColorant = read_tag_XYZType(src, index, TAG_bXYZ); - profile->greenColorant = read_tag_XYZType(src, index, TAG_gXYZ); - - if (!src->valid) - goto invalid_tag_table; - - profile->redTRC = read_tag_curveType(src, index, TAG_rTRC); - profile->blueTRC = read_tag_curveType(src, index, TAG_bTRC); - profile->greenTRC = read_tag_curveType(src, index, TAG_gTRC); - - if (!profile->redTRC || !profile->blueTRC || !profile->greenTRC) - goto invalid_tag_table; - - } else if (profile->color_space == GRAY_SIGNATURE) { - - profile->grayTRC = read_tag_curveType(src, index, TAG_kTRC); - if (!profile->grayTRC) - goto invalid_tag_table; - - } else { - goto invalid_tag_table; - } - } else if (0 && profile->class == OUTPUT_DEVICE_PROFILE) { - profile->A2B0 = read_tag_lutType(src, index, TAG_A2B0); - } else { - goto invalid_tag_table; - } - - if (!src->valid) - goto invalid_tag_table; - - free(index.tags); - - return profile; - -invalid_tag_table: - free(index.tags); -invalid_profile: - qcms_profile_fini(profile); - return INVALID_PROFILE; -} - -qcms_intent qcms_profile_get_rendering_intent(qcms_profile *profile) -{ - return profile->rendering_intent; -} - -icColorSpaceSignature -qcms_profile_get_color_space(qcms_profile *profile) -{ - return profile->color_space; -} - -void qcms_profile_release(qcms_profile *profile) -{ - if (profile->output_table_r) - precache_release(profile->output_table_r); - if (profile->output_table_g) - precache_release(profile->output_table_g); - if (profile->output_table_b) - precache_release(profile->output_table_b); - - qcms_profile_fini(profile); -} - -#include -qcms_profile* qcms_profile_from_file(FILE *file) -{ - uint32_t length, remaining_length; - qcms_profile *profile; - size_t read_length; - __be32 length_be; - void *data; - - fread(&length_be, sizeof(length), 1, file); - length = be32_to_cpu(length_be); - if (length > MAX_PROFILE_SIZE) - return BAD_VALUE_PROFILE; - - /* allocate room for the entire profile */ - data = malloc(length); - if (!data) - return NO_MEM_PROFILE; - - /* copy in length to the front so that the buffer will contain the entire profile */ - *((__be32*)data) = length_be; - remaining_length = length - sizeof(length_be); - - /* read the rest profile */ - read_length = fread((unsigned char*)data + sizeof(length_be), 1, remaining_length, file); - if (read_length != remaining_length) - return INVALID_PROFILE; - - profile = qcms_profile_from_memory(data, length); - free(data); - return profile; -} - -qcms_profile* qcms_profile_from_path(const char *path) -{ - qcms_profile *profile = NULL; - FILE *file = fopen(path, "r"); - if (file) { - profile = qcms_profile_from_file(file); - fclose(file); - } - return profile; -} diff --git a/gfx/qcms/qcms.h b/gfx/qcms/qcms.h deleted file mode 100644 index d45e89c3495..00000000000 --- a/gfx/qcms/qcms.h +++ /dev/null @@ -1,153 +0,0 @@ -#ifndef QCMS_H -#define QCMS_H - -#ifdef __cplusplus -extern "C" { -#endif - -/* if we've already got an ICC_H header we can ignore the following */ -#ifndef ICC_H -/* icc34 defines */ - -/***************************************************************** - Copyright (c) 1994-1996 SunSoft, Inc. - - Rights Reserved - -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 restrict- -ion, 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 NON- -INFRINGEMENT. IN NO EVENT SHALL SUNSOFT, INC. OR ITS PARENT -COMPANY 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. - -Except as contained in this notice, the name of SunSoft, Inc. -shall not be used in advertising or otherwise to promote the -sale, use or other dealings in this Software without written -authorization from SunSoft Inc. -******************************************************************/ - -/* - * Color Space Signatures - * Note that only icSigXYZData and icSigLabData are valid - * Profile Connection Spaces (PCSs) - */ -typedef enum { - icSigXYZData = 0x58595A20L, /* 'XYZ ' */ - icSigLabData = 0x4C616220L, /* 'Lab ' */ - icSigLuvData = 0x4C757620L, /* 'Luv ' */ - icSigYCbCrData = 0x59436272L, /* 'YCbr' */ - icSigYxyData = 0x59787920L, /* 'Yxy ' */ - icSigRgbData = 0x52474220L, /* 'RGB ' */ - icSigGrayData = 0x47524159L, /* 'GRAY' */ - icSigHsvData = 0x48535620L, /* 'HSV ' */ - icSigHlsData = 0x484C5320L, /* 'HLS ' */ - icSigCmykData = 0x434D594BL, /* 'CMYK' */ - icSigCmyData = 0x434D5920L, /* 'CMY ' */ - icSig2colorData = 0x32434C52L, /* '2CLR' */ - icSig3colorData = 0x33434C52L, /* '3CLR' */ - icSig4colorData = 0x34434C52L, /* '4CLR' */ - icSig5colorData = 0x35434C52L, /* '5CLR' */ - icSig6colorData = 0x36434C52L, /* '6CLR' */ - icSig7colorData = 0x37434C52L, /* '7CLR' */ - icSig8colorData = 0x38434C52L, /* '8CLR' */ - icSig9colorData = 0x39434C52L, /* '9CLR' */ - icSig10colorData = 0x41434C52L, /* 'ACLR' */ - icSig11colorData = 0x42434C52L, /* 'BCLR' */ - icSig12colorData = 0x43434C52L, /* 'CCLR' */ - icSig13colorData = 0x44434C52L, /* 'DCLR' */ - icSig14colorData = 0x45434C52L, /* 'ECLR' */ - icSig15colorData = 0x46434C52L, /* 'FCLR' */ - icMaxEnumData = 0xFFFFFFFFL -} icColorSpaceSignature; -#endif - -#include - -typedef int qcms_bool; - -struct _qcms_transform; -typedef struct _qcms_transform qcms_transform; - -struct _qcms_profile; -typedef struct _qcms_profile qcms_profile; - -/* these values match the Rendering Intent values from the ICC spec */ -typedef enum { - QCMS_INTENT_DEFAULT = 0, - QCMS_INTENT_PERCEPTUAL = 0, - QCMS_INTENT_RELATIVE_COLORIMETRIC = 1, - QCMS_INTENT_SATURATION = 2, - QCMS_INTENT_ABSOLUTE_COLORIMETRIC = 3 -} qcms_intent; - -//XXX: I don't really like the _DATA_ prefix -typedef enum { - QCMS_DATA_RGB_8, - QCMS_DATA_RGBA_8, - QCMS_DATA_GRAY_8, - QCMS_DATA_GRAYA_8 -} qcms_data_type; - -/* the names for the following two types are sort of ugly */ -typedef struct -{ - double x; - double y; - double Y; -} qcms_CIE_xyY; - -typedef struct -{ - qcms_CIE_xyY red; - qcms_CIE_xyY green; - qcms_CIE_xyY blue; -} qcms_CIE_xyYTRIPLE; - -qcms_profile* qcms_profile_create_rgb_with_gamma( - qcms_CIE_xyY white_point, - qcms_CIE_xyYTRIPLE primaries, - float gamma); - -qcms_profile* qcms_profile_from_memory(const void *mem, size_t size); - -qcms_profile* qcms_profile_from_file(FILE *file); -qcms_profile* qcms_profile_from_path(const char *path); -qcms_profile* qcms_profile_sRGB(void); -void qcms_profile_release(qcms_profile *profile); - -qcms_bool qcms_profile_is_bogus(qcms_profile *profile); -qcms_intent qcms_profile_get_rendering_intent(qcms_profile *profile); -icColorSpaceSignature qcms_profile_get_color_space(qcms_profile *profile); - -void qcms_profile_precache_output_transform(qcms_profile *profile); - -qcms_transform* qcms_transform_create( - qcms_profile *in, qcms_data_type in_type, - qcms_profile* out, qcms_data_type out_type, - qcms_intent intent); - -void qcms_transform_release(qcms_transform *); - -void qcms_transform_data(qcms_transform *transform, void *src, void *dest, size_t length); - - - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/gfx/qcms/qcmsint.h b/gfx/qcms/qcmsint.h deleted file mode 100644 index a85f278ed5a..00000000000 --- a/gfx/qcms/qcmsint.h +++ /dev/null @@ -1,143 +0,0 @@ -#include -#include "qcms.h" -#include "qcmstypes.h" - -/* used as a 16bit lookup table for the output transformation. - * we refcount them so we only need to have one around per output - * profile, instead of duplicating them per transform */ -struct precache_output -{ - int ref_count; - uint8_t data[65535]; -}; - -#ifdef _MSC_VER -#define ALIGN __declspec(align(16)) -#else -#define ALIGN __attribute__(( aligned (16) )) -#endif - -struct _qcms_transform { - float ALIGN matrix[3][4]; - float *input_gamma_table_r; - float *input_gamma_table_g; - float *input_gamma_table_b; - - float *input_gamma_table_gray; - - float out_gamma_r; - float out_gamma_g; - float out_gamma_b; - - float out_gamma_gray; - - uint16_t *output_gamma_lut_r; - uint16_t *output_gamma_lut_g; - uint16_t *output_gamma_lut_b; - - uint16_t *output_gamma_lut_gray; - - size_t output_gamma_lut_r_length; - size_t output_gamma_lut_g_length; - size_t output_gamma_lut_b_length; - - size_t output_gamma_lut_gray_length; - - struct precache_output *output_table_r; - struct precache_output *output_table_g; - struct precache_output *output_table_b; - - void (*transform_fn)(struct _qcms_transform *transform, unsigned char *src, unsigned char *dest, size_t length); -}; - -typedef int32_t s15Fixed16Number; -typedef uint16_t uInt16Number; - -struct XYZNumber { - s15Fixed16Number X; - s15Fixed16Number Y; - s15Fixed16Number Z; -}; - -struct curveType { - uint32_t count; - uInt16Number data[0]; -}; - -struct lutType { - uint8_t num_input_channels; - uint8_t num_output_channels; - uint8_t num_clut_grid_points; - - s15Fixed16Number e00; - s15Fixed16Number e01; - s15Fixed16Number e02; - s15Fixed16Number e10; - s15Fixed16Number e11; - s15Fixed16Number e12; - s15Fixed16Number e20; - s15Fixed16Number e21; - s15Fixed16Number e22; - - uint16_t num_input_table_entries; - uint16_t num_output_table_entries; - - uint16_t *input_table; - uint16_t *clut_table; - uint16_t *output_table; -}; -#if 0 -this is from an intial idea of having the struct correspond to the data in -the file. I decided that it wasn't a good idea. -struct tag_value { - uint32_t type; - union { - struct { - uint32_t reserved; - struct { - s15Fixed16Number X; - s15Fixed16Number Y; - s15Fixed16Number Z; - } XYZNumber; - } XYZType; - }; -}; // I guess we need to pack this? -#endif - -#define RGB_SIGNATURE 0x52474220 -#define GRAY_SIGNATURE 0x47524159 - -struct _qcms_profile { - uint32_t class; - uint32_t color_space; - qcms_intent rendering_intent; - struct XYZNumber redColorant; - struct XYZNumber blueColorant; - struct XYZNumber greenColorant; - struct curveType *redTRC; - struct curveType *blueTRC; - struct curveType *greenTRC; - struct curveType *grayTRC; - struct lutType *A2B0; - - struct precache_output *output_table_r; - struct precache_output *output_table_g; - struct precache_output *output_table_b; -}; - -#ifdef _MSC_VER -#define inline _inline -#endif - -static inline float s15Fixed16Number_to_float(s15Fixed16Number a) -{ - return ((int32_t)a)/65536.; -} - -static inline s15Fixed16Number double_to_s15Fixed16Number(double v) -{ - return (int32_t)(v*65536); -} - -void precache_release(struct precache_output *p); -void set_rgb_colorants(qcms_profile *profile, qcms_CIE_xyY white_point, qcms_CIE_xyYTRIPLE primaries); diff --git a/gfx/qcms/qcmstypes.h b/gfx/qcms/qcmstypes.h deleted file mode 100644 index b37d88028ab..00000000000 --- a/gfx/qcms/qcmstypes.h +++ /dev/null @@ -1,43 +0,0 @@ -#ifndef QCMS_TYPES_H -#define QCMS_TYPES_H - -#ifdef MOZ_QCMS - -#include "prtypes.h" - -typedef PRInt8 int8_t; -typedef PRUint8 uint8_t; -typedef PRInt16 int16_t; -typedef PRUint16 uint16_t; -typedef PRInt32 int32_t; -typedef PRUint32 uint32_t; -typedef PRInt64 int64_t; -typedef PRUint64 uint64_t; - - -#else - -#if defined (_SVR4) || defined (SVR4) || defined (__OpenBSD__) || defined (_sgi) || defined (__sun) || defined (sun) || defined (__digital__) -# include -#elif defined (_MSC_VER) -typedef __int8 int8_t; -typedef unsigned __int8 uint8_t; -typedef __int16 int16_t; -typedef unsigned __int16 uint16_t; -typedef __int32 int32_t; -typedef unsigned __int32 uint32_t; -typedef __int64 int64_t; -typedef unsigned __int64 uint64_t; -#elif defined (_AIX) -# include -#else -# include -#endif - -#endif - -typedef qcms_bool bool; -#define true 1 -#define false 0 - -#endif diff --git a/gfx/qcms/transform.c b/gfx/qcms/transform.c deleted file mode 100644 index b6dd6fa68f4..00000000000 --- a/gfx/qcms/transform.c +++ /dev/null @@ -1,1484 +0,0 @@ -// qcms -// Copyright (C) 2009 Mozilla Corporation -// Copyright (C) 1998-2007 Marti Maria -// -// 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. - -#include -#include -#include -#include "qcmsint.h" - -#if defined(_M_IX86) || defined(__i386__) -#define X86 -#endif - -//XXX: could use a bettername -typedef uint16_t uint16_fract_t; - -/* value must be a value between 0 and 1 */ -//XXX: is the above a good restriction to have? -float lut_interp_linear(double value, uint16_t *table, int length) -{ - int upper, lower; - value = value * (length - 1); - upper = ceil(value); - lower = floor(value); - //XXX: can we be more performant here? - value = table[upper]*(1. - (upper - value)) + table[lower]*(upper - value); - /* scale the value */ - return value * (1./65535.); -} - -/* same as above but takes and returns a uint16_t value representing a range from 0..1 */ -uint16_t lut_interp_linear16(uint16_t input_value, uint16_t *table, int length) -{ - uint32_t value = (input_value * (length - 1)); - uint32_t upper = (value + 65534) / 65535; /* equivalent to ceil(value/65535) */ - uint32_t lower = value / 65535; /* equivalent to floor(value/65535) */ - uint32_t interp = value % 65535; - - value = (table[upper]*(interp) + table[lower]*(65535 - interp))/65535; - - return value; -} - -void compute_curve_gamma_table_type1(float gamma_table[256], double gamma) -{ - unsigned int i; - for (i = 0; i < 256; i++) { - gamma_table[i] = pow(i/255., gamma); - } -} - -void compute_curve_gamma_table_type2(float gamma_table[256], uint16_t *table, int length) -{ - unsigned int i; - for (i = 0; i < 256; i++) { - gamma_table[i] = lut_interp_linear(i/255., table, length); - } -} - -void compute_curve_gamma_table_type0(float gamma_table[256]) -{ - unsigned int i; - for (i = 0; i < 256; i++) { - gamma_table[i] = i; - } -} - -unsigned char clamp_u8(float v) -{ - if (v > 255.) - return 255; - else if (v < 0) - return 0; - else - return floor(v+.5); -} - -struct vector { - float v[3]; -}; - -struct matrix { - float m[3][3]; - bool invalid; -}; - -struct vector matrix_eval(struct matrix mat, struct vector v) -{ - struct vector result; - result.v[0] = mat.m[0][0]*v.v[0] + mat.m[0][1]*v.v[1] + mat.m[0][2]*v.v[2]; - result.v[1] = mat.m[1][0]*v.v[0] + mat.m[1][1]*v.v[1] + mat.m[1][2]*v.v[2]; - result.v[2] = mat.m[2][0]*v.v[0] + mat.m[2][1]*v.v[1] + mat.m[2][2]*v.v[2]; - return result; -} - -//XXX: should probably pass by reference and we could -//probably reuse this computation in matrix_invert -float matrix_det(struct matrix mat) -{ - float det; - det = mat.m[0][0]*mat.m[1][1]*mat.m[2][2] + - mat.m[0][1]*mat.m[1][2]*mat.m[2][0] + - mat.m[0][2]*mat.m[1][0]*mat.m[2][1] - - mat.m[0][0]*mat.m[1][2]*mat.m[2][1] - - mat.m[0][1]*mat.m[1][0]*mat.m[2][2] - - mat.m[0][2]*mat.m[1][1]*mat.m[2][0]; - return det; -} - -/* from pixman and cairo and Mathematics for Game Programmers */ -/* lcms uses gauss-jordan elimination with partial pivoting which is - * less efficient and not as numerically stable. See Mathematics for - * Game Programmers. */ -struct matrix matrix_invert(struct matrix mat) -{ - struct matrix dest_mat; - int i,j; - static int a[3] = { 2, 2, 1 }; - static int b[3] = { 1, 0, 0 }; - - /* inv (A) = 1/det (A) * adj (A) */ - float det = matrix_det(mat); - - if (det == 0) { - dest_mat.invalid = true; - } else { - dest_mat.invalid = false; - } - - det = 1/det; - - for (j = 0; j < 3; j++) { - for (i = 0; i < 3; i++) { - double p; - int ai = a[i]; - int aj = a[j]; - int bi = b[i]; - int bj = b[j]; - - p = mat.m[ai][aj] * mat.m[bi][bj] - - mat.m[ai][bj] * mat.m[bi][aj]; - if (((i + j) & 1) != 0) - p = -p; - - dest_mat.m[j][i] = det * p; - } - } - return dest_mat; -} - -struct matrix matrix_identity(void) -{ - struct matrix i; - i.m[0][0] = 1; - i.m[0][1] = 0; - i.m[0][2] = 0; - i.m[1][0] = 0; - i.m[1][1] = 1; - i.m[1][2] = 0; - i.m[2][0] = 0; - i.m[2][1] = 0; - i.m[2][2] = 1; - i.invalid = false; - return i; -} - -/* from pixman */ -/* MAT3per... */ -struct matrix matrix_multiply(struct matrix a, struct matrix b) -{ - struct matrix result; - int dx, dy; - int o; - for (dy = 0; dy < 3; dy++) { - for (dx = 0; dx < 3; dx++) { - double v = 0; - for (o = 0; o < 3; o++) { - v += a.m[dy][o] * b.m[o][dx]; - } - result.m[dy][dx] = v; - } - } - result.invalid = a.invalid || b.invalid; - return result; -} - -float u8Fixed8Number_to_float(uint16_t x) -{ - // 0x0000 = 0. - // 0x0100 = 1. - // 0xffff = 255 + 255/256 - return x/256.; -} - -float *build_input_gamma_table(struct curveType *TRC) -{ - float *gamma_table = malloc(sizeof(float)*256); - if (gamma_table) { - if (TRC->count == 0) { - compute_curve_gamma_table_type0(gamma_table); - } else if (TRC->count == 1) { - compute_curve_gamma_table_type1(gamma_table, u8Fixed8Number_to_float(TRC->data[0])); - } else { - compute_curve_gamma_table_type2(gamma_table, TRC->data, TRC->count); - } - } - return gamma_table; -} - -struct matrix build_colorant_matrix(qcms_profile *p) -{ - struct matrix result; - result.m[0][0] = s15Fixed16Number_to_float(p->redColorant.X); - result.m[0][1] = s15Fixed16Number_to_float(p->greenColorant.X); - result.m[0][2] = s15Fixed16Number_to_float(p->blueColorant.X); - result.m[1][0] = s15Fixed16Number_to_float(p->redColorant.Y); - result.m[1][1] = s15Fixed16Number_to_float(p->greenColorant.Y); - result.m[1][2] = s15Fixed16Number_to_float(p->blueColorant.Y); - result.m[2][0] = s15Fixed16Number_to_float(p->redColorant.Z); - result.m[2][1] = s15Fixed16Number_to_float(p->greenColorant.Z); - result.m[2][2] = s15Fixed16Number_to_float(p->blueColorant.Z); - result.invalid = false; - return result; -} - -/* The following code is copied nearly directly from lcms. - * I think it could be much better. For example, Argyll seems to have better code in - * icmTable_lookup_bwd and icmTable_setup_bwd. However, for now this is a quick way - * to a working solution and allows for easy comparing with lcms. */ -uint16_fract_t lut_inverse_interp16(uint16_t Value, uint16_t LutTable[], int length) -{ - int l = 1; - int r = 0x10000; - int x = 0, res; // 'int' Give spacing for negative values - int NumZeroes, NumPoles; - int cell0, cell1; - double val2; - double y0, y1, x0, x1; - double a, b, f; - - // July/27 2001 - Expanded to handle degenerated curves with an arbitrary - // number of elements containing 0 at the begining of the table (Zeroes) - // and another arbitrary number of poles (FFFFh) at the end. - // First the zero and pole extents are computed, then value is compared. - - NumZeroes = 0; - while (LutTable[NumZeroes] == 0 && NumZeroes < length-1) - NumZeroes++; - - // There are no zeros at the beginning and we are trying to find a zero, so - // return anything. It seems zero would be the less destructive choice - /* I'm not sure that this makes sense, but oh well... */ - if (NumZeroes == 0 && Value == 0) - return 0; - - NumPoles = 0; - while (LutTable[length-1- NumPoles] == 0xFFFF && NumPoles < length-1) - NumPoles++; - - // Does the curve belong to this case? - if (NumZeroes > 1 || NumPoles > 1) - { - int a, b; - - // Identify if value fall downto 0 or FFFF zone - if (Value == 0) return 0; - // if (Value == 0xFFFF) return 0xFFFF; - - // else restrict to valid zone - - a = ((NumZeroes-1) * 0xFFFF) / (length-1); - b = ((length-1 - NumPoles) * 0xFFFF) / (length-1); - - l = a - 1; - r = b + 1; - } - - - // Seems not a degenerated case... apply binary search - - while (r > l) { - - x = (l + r) / 2; - - res = (int) lut_interp_linear16((uint16_fract_t) (x-1), LutTable, length); - - if (res == Value) { - - // Found exact match. - - return (uint16_fract_t) (x - 1); - } - - if (res > Value) r = x - 1; - else l = x + 1; - } - - // Not found, should we interpolate? - - - // Get surrounding nodes - - val2 = (length-1) * ((double) (x - 1) / 65535.0); - - cell0 = (int) floor(val2); - cell1 = (int) ceil(val2); - - if (cell0 == cell1) return (uint16_fract_t) x; - - y0 = LutTable[cell0] ; - x0 = (65535.0 * cell0) / (length-1); - - y1 = LutTable[cell1] ; - x1 = (65535.0 * cell1) / (length-1); - - a = (y1 - y0) / (x1 - x0); - b = y0 - a * x0; - - if (fabs(a) < 0.01) return (uint16_fract_t) x; - - f = ((Value - b) / a); - - if (f < 0.0) return (uint16_fract_t) 0; - if (f >= 65535.0) return (uint16_fract_t) 0xFFFF; - - return (uint16_fract_t) floor(f + 0.5); - -} - -// Build a White point, primary chromas transfer matrix from RGB to CIE XYZ -// This is just an approximation, I am not handling all the non-linear -// aspects of the RGB to XYZ process, and assumming that the gamma correction -// has transitive property in the tranformation chain. -// -// the alghoritm: -// -// - First I build the absolute conversion matrix using -// primaries in XYZ. This matrix is next inverted -// - Then I eval the source white point across this matrix -// obtaining the coeficients of the transformation -// - Then, I apply these coeficients to the original matrix -static struct matrix build_RGB_to_XYZ_transfer_matrix(qcms_CIE_xyY white, qcms_CIE_xyYTRIPLE primrs) -{ - struct matrix primaries; - struct matrix primaries_invert; - struct matrix result; - struct vector white_point; - struct vector coefs; - - double xn, yn; - double xr, yr; - double xg, yg; - double xb, yb; - - xn = white.x; - yn = white.y; - - xr = primrs.red.x; - yr = primrs.red.y; - xg = primrs.green.x; - yg = primrs.green.y; - xb = primrs.blue.x; - yb = primrs.blue.y; - - primaries.m[0][0] = xr; - primaries.m[0][1] = xg; - primaries.m[0][2] = xb; - - primaries.m[1][0] = yr; - primaries.m[1][1] = yg; - primaries.m[1][2] = yb; - - primaries.m[2][0] = 1 - xr - yr; - primaries.m[2][1] = 1 - xg - yg; - primaries.m[2][2] = 1 - xb - yb; - primaries.invalid = false; - - white_point.v[0] = xn/yn; - white_point.v[1] = 1.; - white_point.v[2] = (1.0-xn-yn)/yn; - - primaries_invert = matrix_invert(primaries); - - coefs = matrix_eval(primaries_invert, white_point); - - result.m[0][0] = coefs.v[0]*xr; - result.m[0][1] = coefs.v[1]*xg; - result.m[0][2] = coefs.v[2]*xb; - - result.m[1][0] = coefs.v[0]*yr; - result.m[1][1] = coefs.v[1]*yg; - result.m[1][2] = coefs.v[2]*yb; - - result.m[2][0] = coefs.v[0]*(1.-xr-yr); - result.m[2][1] = coefs.v[1]*(1.-xg-yg); - result.m[2][2] = coefs.v[2]*(1.-xb-yb); - result.invalid = primaries_invert.invalid; - - return result; -} - -struct CIE_XYZ { - double X; - double Y; - double Z; -}; - -/* CIE Illuminant D50 */ -static const struct CIE_XYZ D50_XYZ = { - 0.9642, - 1.0000, - 0.8249 -}; - -/* from lcms: xyY2XYZ() - * corresponds to argyll: icmYxy2XYZ() */ -static struct CIE_XYZ xyY2XYZ(qcms_CIE_xyY source) -{ - struct CIE_XYZ dest; - dest.X = (source.x / source.y) * source.Y; - dest.Y = source.Y; - dest.Z = ((1 - source.x - source.y) / source.y) * source.Y; - return dest; -} - -/* from lcms: ComputeChromaticAdaption */ -// Compute chromatic adaption matrix using chad as cone matrix -static struct matrix -compute_chromatic_adaption(struct CIE_XYZ source_white_point, - struct CIE_XYZ dest_white_point, - struct matrix chad) -{ - struct matrix chad_inv; - struct vector cone_source_XYZ, cone_source_rgb; - struct vector cone_dest_XYZ, cone_dest_rgb; - struct matrix cone, tmp; - - tmp = chad; - chad_inv = matrix_invert(tmp); - - cone_source_XYZ.v[0] = source_white_point.X; - cone_source_XYZ.v[1] = source_white_point.Y; - cone_source_XYZ.v[2] = source_white_point.Z; - - cone_dest_XYZ.v[0] = dest_white_point.X; - cone_dest_XYZ.v[1] = dest_white_point.Y; - cone_dest_XYZ.v[2] = dest_white_point.Z; - - cone_source_rgb = matrix_eval(chad, cone_source_XYZ); - cone_dest_rgb = matrix_eval(chad, cone_dest_XYZ); - - cone.m[0][0] = cone_dest_rgb.v[0]/cone_source_rgb.v[0]; - cone.m[0][1] = 0; - cone.m[0][2] = 0; - cone.m[1][0] = 0; - cone.m[1][1] = cone_dest_rgb.v[1]/cone_source_rgb.v[1]; - cone.m[1][2] = 0; - cone.m[2][0] = 0; - cone.m[2][1] = 0; - cone.m[2][2] = cone_dest_rgb.v[2]/cone_source_rgb.v[2]; - cone.invalid = false; - - // Normalize - return matrix_multiply(chad_inv, matrix_multiply(cone, chad)); -} - -/* from lcms: cmsAdaptionMatrix */ -// Returns the final chrmatic adaptation from illuminant FromIll to Illuminant ToIll -// Bradford is assumed -static struct matrix -adaption_matrix(struct CIE_XYZ source_illumination, struct CIE_XYZ target_illumination) -{ - struct matrix lam_rigg = {{ // Bradford matrix - { 0.8951, 0.2664, -0.1614 }, - { -0.7502, 1.7135, 0.0367 }, - { 0.0389, -0.0685, 1.0296 } - }}; - return compute_chromatic_adaption(source_illumination, target_illumination, lam_rigg); -} - -/* from lcms: cmsAdaptMatrixToD50 */ -static struct matrix adapt_matrix_to_D50(struct matrix r, qcms_CIE_xyY source_white_pt) -{ - struct CIE_XYZ Dn; - struct matrix Bradford; - Dn = xyY2XYZ(source_white_pt); - - Bradford = adaption_matrix(Dn, D50_XYZ); - return matrix_multiply(Bradford, r); -} - -void set_rgb_colorants(qcms_profile *profile, qcms_CIE_xyY white_point, qcms_CIE_xyYTRIPLE primaries) -{ - struct matrix colorants; - colorants = build_RGB_to_XYZ_transfer_matrix(white_point, primaries); - colorants = adapt_matrix_to_D50(colorants, white_point); - - /* note: there's a transpose type of operation going on here */ - profile->redColorant.X = double_to_s15Fixed16Number(colorants.m[0][0]); - profile->redColorant.Y = double_to_s15Fixed16Number(colorants.m[1][0]); - profile->redColorant.Z = double_to_s15Fixed16Number(colorants.m[2][0]); - - profile->greenColorant.X = double_to_s15Fixed16Number(colorants.m[0][1]); - profile->greenColorant.Y = double_to_s15Fixed16Number(colorants.m[1][1]); - profile->greenColorant.Z = double_to_s15Fixed16Number(colorants.m[2][1]); - - profile->blueColorant.X = double_to_s15Fixed16Number(colorants.m[0][2]); - profile->blueColorant.Y = double_to_s15Fixed16Number(colorants.m[1][2]); - profile->blueColorant.Z = double_to_s15Fixed16Number(colorants.m[2][2]); -} - -static uint16_t *invert_lut(uint16_t *table, int length) -{ - int i; - /* for now we invert the lut by creating a lut of the same size - * and attempting to lookup a value for each entry using lut_inverse_interp16 */ - uint16_t *output = malloc(sizeof(uint16_t)*length); - if (!output) - return NULL; - - for (i = 0; i < length; i++) { - double x = ((double) i * 65535.) / (double) (length - 1); - uint16_fract_t input = floor(x + .5); - output[i] = lut_inverse_interp16(input, table, length); - } - return output; -} - -static uint16_t *build_linear_table(int length) -{ - int i; - uint16_t *output = malloc(sizeof(uint16_t)*length); - if (!output) - return NULL; - - for (i = 0; i < length; i++) { - double x = ((double) i * 65535.) / (double) (length - 1); - uint16_fract_t input = floor(x + .5); - output[i] = input; - } - return output; -} - -static uint16_t *build_pow_table(float gamma, int length) -{ - int i; - uint16_t *output = malloc(sizeof(uint16_t)*length); - if (!output) - return NULL; - - for (i = 0; i < length; i++) { - uint16_fract_t result; - double x = ((double) i) / (double) (length - 1); - x = pow(x, gamma); - //XXX turn this conversion into a function - result = floor(x*65535. + .5); - output[i] = result; - } - return output; -} - -static float clamp_float(float a) -{ - if (a > 1.) - return 1.; - else if (a < 0) - return 0; - else - return a; -} - -#if 0 -static void qcms_transform_data_rgb_out_pow(qcms_transform *transform, unsigned char *src, unsigned char *dest, size_t length) -{ - int i; - float (*mat)[4] = transform->matrix; - for (i=0; iinput_gamma_table_r[device_r]; - float linear_g = transform->input_gamma_table_g[device_g]; - float linear_b = transform->input_gamma_table_b[device_b]; - - float out_linear_r = mat[0][0]*linear_r + mat[1][0]*linear_g + mat[2][0]*linear_b; - float out_linear_g = mat[0][1]*linear_r + mat[1][1]*linear_g + mat[2][1]*linear_b; - float out_linear_b = mat[0][2]*linear_r + mat[1][2]*linear_g + mat[2][2]*linear_b; - - float out_device_r = pow(out_linear_r, transform->out_gamma_r); - float out_device_g = pow(out_linear_g, transform->out_gamma_g); - float out_device_b = pow(out_linear_b, transform->out_gamma_b); - - *dest++ = clamp_u8(255*out_device_r); - *dest++ = clamp_u8(255*out_device_g); - *dest++ = clamp_u8(255*out_device_b); - } -} -#endif - -static void qcms_transform_data_gray_out_lut(qcms_transform *transform, unsigned char *src, unsigned char *dest, size_t length) -{ - int i; - for (i = 0; i < length; i++) { - float out_device_r, out_device_g, out_device_b; - unsigned char device = *src++; - - float linear = transform->input_gamma_table_gray[device]; - - out_device_r = lut_interp_linear(linear, transform->output_gamma_lut_r, transform->output_gamma_lut_r_length); - out_device_g = lut_interp_linear(linear, transform->output_gamma_lut_g, transform->output_gamma_lut_g_length); - out_device_b = lut_interp_linear(linear, transform->output_gamma_lut_b, transform->output_gamma_lut_b_length); - - *dest++ = clamp_u8(out_device_r*255); - *dest++ = clamp_u8(out_device_g*255); - *dest++ = clamp_u8(out_device_b*255); - } -} - -static void qcms_transform_data_graya_out_lut(qcms_transform *transform, unsigned char *src, unsigned char *dest, size_t length) -{ - int i; - for (i = 0; i < length; i++) { - float out_device_r, out_device_g, out_device_b; - unsigned char device = *src++; - unsigned char alpha = *src++; - - float linear = transform->input_gamma_table_gray[device]; - - out_device_r = lut_interp_linear(linear, transform->output_gamma_lut_r, transform->output_gamma_lut_r_length); - out_device_g = lut_interp_linear(linear, transform->output_gamma_lut_g, transform->output_gamma_lut_g_length); - out_device_b = lut_interp_linear(linear, transform->output_gamma_lut_b, transform->output_gamma_lut_b_length); - - *dest++ = clamp_u8(out_device_r*255); - *dest++ = clamp_u8(out_device_g*255); - *dest++ = clamp_u8(out_device_b*255); - *dest++ = alpha; - } -} - - -static void qcms_transform_data_gray_out_precache(qcms_transform *transform, unsigned char *src, unsigned char *dest, size_t length) -{ - int i; - for (i = 0; i < length; i++) { - unsigned char device = *src++; - uint16_t gray; - - float linear = transform->input_gamma_table_gray[device]; - - /* we could round here... */ - gray = linear * 65535.; - - *dest++ = transform->output_table_r->data[gray]; - *dest++ = transform->output_table_g->data[gray]; - *dest++ = transform->output_table_b->data[gray]; - } -} - -static void qcms_transform_data_graya_out_precache(qcms_transform *transform, unsigned char *src, unsigned char *dest, size_t length) -{ - int i; - for (i = 0; i < length; i++) { - unsigned char device = *src++; - unsigned char alpha = *src++; - uint16_t gray; - - float linear = transform->input_gamma_table_gray[device]; - - /* we could round here... */ - gray = linear * 65535.; - - *dest++ = transform->output_table_r->data[gray]; - *dest++ = transform->output_table_g->data[gray]; - *dest++ = transform->output_table_b->data[gray]; - *dest++ = alpha; - } -} - -static const ALIGN float floatScale = 65536.0f; -static const ALIGN float * const floatScaleAddr = &floatScale; // Win32 ASM doesn't know how to take addressOf inline - -static const ALIGN float clampMaxValue = ((float) (65536 - 1)) / 65536.0f; - -#ifdef X86 -#if 0 -#include -void qcms_transform_data_rgb_out_lut_sse_intrin(qcms_transform *transform, unsigned char *src, unsigned char *dest, size_t length) -{ - int i; - float (*mat)[4] = transform->matrix; - char input_back[32]; - /* Ensure we have a buffer that's 16 byte aligned regardless of the original - * stack alignment. We can't use __attribute__((aligned(16))) or __declspec(align(32)) - * because they don't work on stack variables. gcc 4.4 does do the right thing - * on x86 but that's too new for us right now. For more info: gcc bug #16660 */ - float *input = (float*)(((unsigned long)&input_back[16]) & 0xfffffff0); - /* share input and output locations to save having to keep the - * locations in separate registers */ - uint32_t* output = (uint32_t*)input; - for (i=0; iinput_gamma_table_r[device_r]); - vec_r = _mm_shuffle_ps(vec_r, vec_r, 0); - __m128 vec_g = _mm_load_ss(&transform->input_gamma_table_r[device_g]); - vec_g = _mm_shuffle_ps(vec_g, vec_g, 0); - __m128 vec_b = _mm_load_ss(&transform->input_gamma_table_r[device_b]); - vec_b = _mm_shuffle_ps(vec_b, vec_b, 0); - - vec_r = _mm_mul_ps(vec_r, xmm1); - vec_g = _mm_mul_ps(vec_g, xmm2); - vec_b = _mm_mul_ps(vec_b, xmm3); - - vec_r = _mm_add_ps(vec_r, _mm_add_ps(vec_g, vec_b)); - - __m128 max = _mm_load_ss(&clampMax); - max = _mm_shuffle_ps(max, max, 0); - __m128 min = _mm_setzero_ps(); - - vec_r = _mm_max_ps(min, vec_r); - vec_r = _mm_min_ps(max, vec_r); - - __m128 scale = _mm_load_ss(&floatScale); - scale = _mm_shuffle_ps(scale, scale, 0); - __m128 result = _mm_mul_ps(vec_r, scale); - - __m128i out = _mm_cvtps_epi32(result); - _mm_store_si128((__m128i*)input, out); - - *dest++ = transform->output_table_r->data[output[0]]; - *dest++ = transform->output_table_g->data[output[1]]; - *dest++ = transform->output_table_b->data[output[2]]; - } -} -#endif -static void qcms_transform_data_rgb_out_lut_sse(qcms_transform *transform, unsigned char *src, unsigned char *dest, size_t length) -{ - int i; - float (*mat)[4] = transform->matrix; - char input_back[32]; - /* Ensure we have a buffer that's 16 byte aligned regardless of the original - * stack alignment. We can't use __attribute__((aligned(16))) or __declspec(align(32)) - * because they don't work on stack variables. gcc 4.4 does do the right thing - * on x86 but that's too new for us right now. For more info: gcc bug #16660 */ - float *input = (float*)(((unsigned long)&input_back[16]) & 0xfffffff0); - /* share input and output locations to save having to keep the - * locations in separate registers */ - uint32_t* output = (uint32_t*)input; - for (i = 0; i < length; i++) { - const float *clampMax = &clampMaxValue; - - unsigned char device_r = *src++; - unsigned char device_g = *src++; - unsigned char device_b = *src++; - - input[0] = transform->input_gamma_table_r[device_r]; - input[1] = transform->input_gamma_table_g[device_g]; - input[2] = transform->input_gamma_table_b[device_b]; - -#ifdef __GNUC__ - __asm( - "movaps (%0), %%xmm1;\n\t" // Move the first matrix column to xmm1 - "movaps 16(%0), %%xmm2;\n\t" // Move the second matrix column to xmm2 - "movaps 32(%0), %%xmm3;\n\t" // move the third matrix column to xmm3 - "movaps (%3), %%xmm0;\n\t" // Move the vector to xmm0 - - // Note - We have to copy and then shuffle because of the weird - // semantics of shufps - // - "movaps %%xmm0, %%xmm4;\n\t" // Copy the vector to xmm4 - "shufps $0, %%xmm4, %%xmm4;\n\t" // Shuffle to repeat the first vector element repeated 4 times - "mulps %%xmm4, %%xmm1;\n\t" // Multiply the first vector element by the first matrix column - "movaps %%xmm0, %%xmm5; \n\t" // Copy the vector to xmm5 - "shufps $0x55, %%xmm5, %%xmm5;\n\t" // Shuffle to repeat the second vector element repeated 4 times - "mulps %%xmm5, %%xmm2;\n\t" // Multiply the second vector element by the seccond matrix column - "movaps %%xmm0, %%xmm6;\n\t" // Copy the vector to xmm6 - "shufps $0xAA, %%xmm6, %%xmm6;\n\t" // Shuffle to repeat the third vector element repeated 4 times - "mulps %%xmm6, %%xmm3;\n\t" // Multiply the third vector element by the third matrix column - - "addps %%xmm3, %%xmm2;\n\t" // Sum (second + third) columns - "addps %%xmm2, %%xmm1;\n\t" // Sum ((second + third) + first) columns - - "movss (%1), %%xmm7;\n\t" // load the floating point representation of 65535/65536 - "shufps $0, %%xmm7, %%xmm7;\n\t" // move it into all of the four slots - "minps %%xmm7, %%xmm1;\n\t" // clamp the vector to 1.0 max - "xorps %%xmm6, %%xmm6;\n\t" // get us cleared bitpatern, which is 0.0f - "maxps %%xmm6, %%xmm1;\n\t" // clamp the vector to 0.0 min - "movss (%2), %%xmm5;\n\t" // load the floating point scale factor - "shufps $0, %%xmm5, %%xmm5;\n\t" // put it in all four slots - "mulps %%xmm5, %%xmm1;\n\t" // multiply by the scale factor - "cvtps2dq %%xmm1, %%xmm1;\n\t" // convert to integers - "movdqa %%xmm1, (%3);\n\t" // store - - : - : "r" (mat), "r" (clampMax), "r" (&floatScale), "r" (input) - : "memory" -/* older versions of gcc don't know about these registers so only include them as constraints - if gcc knows about them */ -#ifdef __SSE2__ - , "%xmm0", "%xmm1", "%xmm2", "%xmm3", "%xmm4", "%xmm5", "%xmm6", "%xmm7" -#endif - ); -#else - __asm { - mov eax, mat - mov ecx, clampMax - mov edx, floatScaleAddr - mov ebx, input - - movaps xmm1, [eax] - movaps xmm2, [eax + 16] - movaps xmm3, [eax + 32] - movaps xmm0, [ebx] - - movaps xmm4, xmm0 - shufps xmm4, xmm4, 0 - mulps xmm1, xmm4 - movaps xmm5, xmm0 - shufps xmm5, xmm5, 0x55 - mulps xmm2, xmm5 - movaps xmm6, xmm0 - shufps xmm6, xmm6, 0xAA - mulps xmm3, xmm6 - - addps xmm2, xmm3 - addps xmm1, xmm2 - - movss xmm7, [ecx] - shufps xmm7, xmm7, 0 - minps xmm1, xmm7 - xorps xmm6, xmm6 - maxps xmm1, xmm6 - movss xmm5, [edx] - shufps xmm5, xmm5, 0 - mulps xmm1, xmm5 - cvtps2dq xmm1, xmm1 - movdqa [ebx], xmm1 - } -#endif - - *dest++ = transform->output_table_r->data[output[0]]; - *dest++ = transform->output_table_g->data[output[1]]; - *dest++ = transform->output_table_b->data[output[2]]; - } -} - -static void qcms_transform_data_rgba_out_lut_sse(qcms_transform *transform, unsigned char *src, unsigned char *dest, size_t length) -{ - int i; - float (*mat)[4] = transform->matrix; - char input_back[32]; - float *input = (float*)(((unsigned long)&input_back[16]) & 0xfffffff0); - /* share input and output locations to save having to keep the - * locations in separate registers */ - uint32_t* output = (uint32_t*)input; - for (i = 0; i < length; i++) { - const float *clampMax = &clampMaxValue; - - unsigned char device_r = *src++; - unsigned char device_g = *src++; - unsigned char device_b = *src++; - unsigned char alpha = *src++; - - input[0] = transform->input_gamma_table_r[device_r]; - input[1] = transform->input_gamma_table_g[device_g]; - input[2] = transform->input_gamma_table_b[device_b]; - -#ifdef __GNUC__ - __asm( - "movaps (%0), %%xmm1;\n\t" // Move the first matrix column to xmm1 - "movaps 16(%0), %%xmm2;\n\t" // Move the second matrix column to xmm2 - "movaps 32(%0), %%xmm3;\n\t" // move the third matrix column to xmm3 - "movaps (%3), %%xmm0;\n\t" // Move the vector to xmm0 - - // Note - We have to copy and then shuffle because of the weird - // semantics of shufps - // - "movaps %%xmm0, %%xmm4;\n\t" // Copy the vector to xmm4 - "shufps $0, %%xmm4, %%xmm4;\n\t" // Shuffle to repeat the first vector element repeated 4 times - "mulps %%xmm4, %%xmm1;\n\t" // Multiply the first vector element by the first matrix column - "movaps %%xmm0, %%xmm5; \n\t" // Copy the vector to xmm5 - "shufps $0x55, %%xmm5, %%xmm5;\n\t" // Shuffle to repeat the second vector element repeated 4 times - "mulps %%xmm5, %%xmm2;\n\t" // Multiply the second vector element by the seccond matrix column - "movaps %%xmm0, %%xmm6;\n\t" // Copy the vector to xmm6 - "shufps $0xAA, %%xmm6, %%xmm6;\n\t" // Shuffle to repeat the third vector element repeated 4 times - "mulps %%xmm6, %%xmm3;\n\t" // Multiply the third vector element by the third matrix column - - "addps %%xmm3, %%xmm2;\n\t" // Sum (second + third) columns - "addps %%xmm2, %%xmm1;\n\t" // Sum ((second + third) + first) columns - - "movss (%1), %%xmm7;\n\t" // load the floating point representation of 65535/65536 - "shufps $0, %%xmm7, %%xmm7;\n\t" // move it into all of the four slots - "minps %%xmm7, %%xmm1;\n\t" // clamp the vector to 1.0 max - "xorps %%xmm6, %%xmm6;\n\t" // get us cleared bitpatern, which is 0.0f - "maxps %%xmm6, %%xmm1;\n\t" // clamp the vector to 0.0 min - "movss (%2), %%xmm5;\n\t" // load the floating point scale factor - "shufps $0, %%xmm5, %%xmm5;\n\t" // put it in all four slots - "mulps %%xmm5, %%xmm1;\n\t" // multiply by the scale factor - "cvtps2dq %%xmm1, %%xmm1;\n\t" // convert to integers - "movdqa %%xmm1, (%3);\n\t" // store - - : - : "r" (mat), "r" (clampMax), "r" (&floatScale), "r" (input) - : "memory" -/* older versions of gcc don't know about these registers so only include them as constraints - if gcc knows about them */ -#ifdef __SSE2__ - , "%xmm0", "%xmm1", "%xmm2", "%xmm3", "%xmm4", "%xmm5", "%xmm6", "%xmm7" -#endif - ); -#else - __asm { - mov eax, mat - mov ecx, clampMax - mov edx, floatScaleAddr - mov ebx, input - - movaps xmm1, [eax] - movaps xmm2, [eax + 16] - movaps xmm3, [eax + 32] - movaps xmm0, [ebx] - - movaps xmm4, xmm0 - shufps xmm4, xmm4, 0 - mulps xmm1, xmm4 - movaps xmm5, xmm0 - shufps xmm5, xmm5, 0x55 - mulps xmm2, xmm5 - movaps xmm6, xmm0 - shufps xmm6, xmm6, 0xAA - mulps xmm3, xmm6 - - addps xmm2, xmm3 - addps xmm1, xmm2 - - movss xmm7, [ecx] - shufps xmm7, xmm7, 0 - minps xmm1, xmm7 - xorps xmm6, xmm6 - maxps xmm1, xmm6 - movss xmm5, [edx] - shufps xmm5, xmm5, 0 - mulps xmm1, xmm5 - cvtps2dq xmm1, xmm1 - movdqa [ebx], xmm1 - } -#endif - - *dest++ = transform->output_table_r->data[output[0]]; - *dest++ = transform->output_table_g->data[output[1]]; - *dest++ = transform->output_table_b->data[output[2]]; - *dest++ = alpha; - } -} -#endif - -static void qcms_transform_data_rgb_out_lut_precache(qcms_transform *transform, unsigned char *src, unsigned char *dest, size_t length) -{ - int i; - float (*mat)[4] = transform->matrix; - for (i = 0; i < length; i++) { - unsigned char device_r = *src++; - unsigned char device_g = *src++; - unsigned char device_b = *src++; - uint16_t r, g, b; - - float linear_r = transform->input_gamma_table_r[device_r]; - float linear_g = transform->input_gamma_table_g[device_g]; - float linear_b = transform->input_gamma_table_b[device_b]; - - float out_linear_r = mat[0][0]*linear_r + mat[1][0]*linear_g + mat[2][0]*linear_b; - float out_linear_g = mat[0][1]*linear_r + mat[1][1]*linear_g + mat[2][1]*linear_b; - float out_linear_b = mat[0][2]*linear_r + mat[1][2]*linear_g + mat[2][2]*linear_b; - - out_linear_r = clamp_float(out_linear_r); - out_linear_g = clamp_float(out_linear_g); - out_linear_b = clamp_float(out_linear_b); - - /* we could round here... */ - r = out_linear_r * 65535.; - g = out_linear_g * 65535.; - b = out_linear_b * 65535.; - - *dest++ = transform->output_table_r->data[r]; - *dest++ = transform->output_table_g->data[g]; - *dest++ = transform->output_table_b->data[b]; - } -} - -static void qcms_transform_data_rgba_out_lut_precache(qcms_transform *transform, unsigned char *src, unsigned char *dest, size_t length) -{ - int i; - float (*mat)[4] = transform->matrix; - for (i = 0; i < length; i++) { - unsigned char device_r = *src++; - unsigned char device_g = *src++; - unsigned char device_b = *src++; - unsigned char alpha = *src++; - uint16_t r, g, b; - - float linear_r = transform->input_gamma_table_r[device_r]; - float linear_g = transform->input_gamma_table_g[device_g]; - float linear_b = transform->input_gamma_table_b[device_b]; - - float out_linear_r = mat[0][0]*linear_r + mat[1][0]*linear_g + mat[2][0]*linear_b; - float out_linear_g = mat[0][1]*linear_r + mat[1][1]*linear_g + mat[2][1]*linear_b; - float out_linear_b = mat[0][2]*linear_r + mat[1][2]*linear_g + mat[2][2]*linear_b; - - out_linear_r = clamp_float(out_linear_r); - out_linear_g = clamp_float(out_linear_g); - out_linear_b = clamp_float(out_linear_b); - - /* we could round here... */ - r = out_linear_r * 65535.; - g = out_linear_g * 65535.; - b = out_linear_b * 65535.; - - *dest++ = transform->output_table_r->data[r]; - *dest++ = transform->output_table_g->data[g]; - *dest++ = transform->output_table_b->data[b]; - *dest++ = alpha; - } -} - -static void qcms_transform_data_rgb_out_lut(qcms_transform *transform, unsigned char *src, unsigned char *dest, size_t length) -{ - int i; - float (*mat)[4] = transform->matrix; - for (i = 0; i < length; i++) { - unsigned char device_r = *src++; - unsigned char device_g = *src++; - unsigned char device_b = *src++; - float out_device_r, out_device_g, out_device_b; - - float linear_r = transform->input_gamma_table_r[device_r]; - float linear_g = transform->input_gamma_table_g[device_g]; - float linear_b = transform->input_gamma_table_b[device_b]; - - float out_linear_r = mat[0][0]*linear_r + mat[1][0]*linear_g + mat[2][0]*linear_b; - float out_linear_g = mat[0][1]*linear_r + mat[1][1]*linear_g + mat[2][1]*linear_b; - float out_linear_b = mat[0][2]*linear_r + mat[1][2]*linear_g + mat[2][2]*linear_b; - - out_linear_r = clamp_float(out_linear_r); - out_linear_g = clamp_float(out_linear_g); - out_linear_b = clamp_float(out_linear_b); - - out_device_r = lut_interp_linear(out_linear_r, transform->output_gamma_lut_r, transform->output_gamma_lut_r_length); - out_device_g = lut_interp_linear(out_linear_g, transform->output_gamma_lut_g, transform->output_gamma_lut_g_length); - out_device_b = lut_interp_linear(out_linear_b, transform->output_gamma_lut_b, transform->output_gamma_lut_b_length); - - *dest++ = clamp_u8(out_device_r*255); - *dest++ = clamp_u8(out_device_g*255); - *dest++ = clamp_u8(out_device_b*255); - } -} - -static void qcms_transform_data_rgba_out_lut(qcms_transform *transform, unsigned char *src, unsigned char *dest, size_t length) -{ - int i; - float (*mat)[4] = transform->matrix; - for (i = 0; i < length; i++) { - unsigned char device_r = *src++; - unsigned char device_g = *src++; - unsigned char device_b = *src++; - unsigned char alpha = *src++; - float out_device_r, out_device_g, out_device_b; - - float linear_r = transform->input_gamma_table_r[device_r]; - float linear_g = transform->input_gamma_table_g[device_g]; - float linear_b = transform->input_gamma_table_b[device_b]; - - float out_linear_r = mat[0][0]*linear_r + mat[1][0]*linear_g + mat[2][0]*linear_b; - float out_linear_g = mat[0][1]*linear_r + mat[1][1]*linear_g + mat[2][1]*linear_b; - float out_linear_b = mat[0][2]*linear_r + mat[1][2]*linear_g + mat[2][2]*linear_b; - - out_linear_r = clamp_float(out_linear_r); - out_linear_g = clamp_float(out_linear_g); - out_linear_b = clamp_float(out_linear_b); - - out_device_r = lut_interp_linear(out_linear_r, transform->output_gamma_lut_r, transform->output_gamma_lut_r_length); - out_device_g = lut_interp_linear(out_linear_g, transform->output_gamma_lut_g, transform->output_gamma_lut_g_length); - out_device_b = lut_interp_linear(out_linear_b, transform->output_gamma_lut_b, transform->output_gamma_lut_b_length); - - *dest++ = clamp_u8(out_device_r*255); - *dest++ = clamp_u8(out_device_g*255); - *dest++ = clamp_u8(out_device_b*255); - *dest++ = alpha; - } -} - -#if 0 -static void qcms_transform_data_rgb_out_linear(qcms_transform *transform, unsigned char *src, unsigned char *dest, size_t length) -{ - int i; - float (*mat)[4] = transform->matrix; - for (i = 0; i < length; i++) { - unsigned char device_r = *src++; - unsigned char device_g = *src++; - unsigned char device_b = *src++; - - float linear_r = transform->input_gamma_table_r[device_r]; - float linear_g = transform->input_gamma_table_g[device_g]; - float linear_b = transform->input_gamma_table_b[device_b]; - - float out_linear_r = mat[0][0]*linear_r + mat[1][0]*linear_g + mat[2][0]*linear_b; - float out_linear_g = mat[0][1]*linear_r + mat[1][1]*linear_g + mat[2][1]*linear_b; - float out_linear_b = mat[0][2]*linear_r + mat[1][2]*linear_g + mat[2][2]*linear_b; - - *dest++ = clamp_u8(out_linear_r*255); - *dest++ = clamp_u8(out_linear_g*255); - *dest++ = clamp_u8(out_linear_b*255); - } -} -#endif - -static struct precache_output *precache_reference(struct precache_output *p) -{ - p->ref_count++; - return p; -} - -static struct precache_output *precache_create() -{ - struct precache_output *p = malloc(sizeof(struct precache_output)); - p->ref_count = 1; - return p; -} - -void precache_release(struct precache_output *p) -{ - if (--p->ref_count == 0) { - free(p); - } -} - -void qcms_transform_release(qcms_transform *t) -{ - /* ensure we only free the gamma tables once even if there are - * multiple references to the same data */ - - if (t->output_table_r) - precache_release(t->output_table_r); - if (t->output_table_g) - precache_release(t->output_table_g); - if (t->output_table_b) - precache_release(t->output_table_b); - - free(t->input_gamma_table_r); - if (t->input_gamma_table_g != t->input_gamma_table_r) - free(t->input_gamma_table_g); - if (t->input_gamma_table_g != t->input_gamma_table_r && - t->input_gamma_table_g != t->input_gamma_table_b) - free(t->input_gamma_table_b); - - free(t->input_gamma_table_gray); - - free(t->output_gamma_lut_r); - free(t->output_gamma_lut_g); - free(t->output_gamma_lut_b); - - free(t); -} - -static void compute_precache_pow(uint8_t *output, float gamma) -{ - uint32_t v = 0; - for (v = 0; v <= 0xffff; v++) { - //XXX: don't do integer/float conversion... and round? - output[v] = 255. * pow(v/65535., gamma); - } -} - -void compute_precache_lut(uint8_t *output, uint16_t *table, int length) -{ - uint32_t v = 0; - for (v = 0; v <= 0xffff; v++) { - //XXX: don't do integer/float conversion... round? - output[v] = lut_interp_linear16(v, table, length) >> 8; - } -} - -void compute_precache_linear(uint8_t *output) -{ - uint32_t v = 0; - for (v = 0; v <= 0xffff; v++) { - //XXX: round? - output[v] = v >> 8; - } -} - -qcms_bool compute_precache(struct curveType *trc, uint8_t *output) -{ - if (trc->count == 0) { - compute_precache_linear(output); - } else if (trc->count == 1) { - compute_precache_pow(output, 1./u8Fixed8Number_to_float(trc->data[0])); - } else { - uint16_t *inverted = invert_lut(trc->data, trc->count); - if (!inverted) - return false; - compute_precache_lut(output, inverted, trc->count); - free(inverted); - } - return true; -} - - -// Determine if we can build with SSE2 (this was partly copied from jmorecfg.h in -// mozilla/jpeg) - // ------------------------------------------------------------------------- -#if defined(_M_IX86) && defined(_MSC_VER_) -#define HAS_CPUID -/* Get us a CPUID function. Avoid clobbering EBX because sometimes it's the PIC - register - I'm not sure if that ever happens on windows, but cpuid isn't - on the critical path so we just preserve the register to be safe and to be - consistent with the non-windows version. */ -static void cpuid(uint32_t fxn, uint32_t *a, uint32_t *b, uint32_t *c, uint32_t *d) { - uint32_t a_, b_, c_, d_; - __asm { - xchg ebx, esi - mov eax, fxn - cpuid - mov a_, eax - mov b_, ebx - mov c_, ecx - mov d_, edx - xchg ebx, esi - } - *a = a_; - *b = b_; - *c = c_; - *d = d_; -} -#elif defined(__GNUC__) && defined(__i386__) -#define HAS_CPUID -/* Get us a CPUID function. We can't use ebx because it's the PIC register on - some platforms, so we use ESI instead and save ebx to avoid clobbering it. */ -static void cpuid(uint32_t fxn, uint32_t *a, uint32_t *b, uint32_t *c, uint32_t *d) { - - uint32_t a_, b_, c_, d_; - __asm__ __volatile__ ("xchgl %%ebx, %%esi; cpuid; xchgl %%ebx, %%esi;" - : "=a" (a_), "=S" (b_), "=c" (c_), "=d" (d_) : "a" (fxn)); - *a = a_; - *b = b_; - *c = c_; - *d = d_; -} -#endif - -// -------------------------Runtime SSE2 Detection----------------------------- - -#define SSE2_EDX_MASK (1UL << 26) -static qcms_bool sse2_available(void) -{ -#ifdef HAS_CPUID - static int has_sse2 = -1; - uint32_t a, b, c, d; - uint32_t function = 0x00000001; - - if (has_sse2 == -1) { - has_sse2 = 0; - cpuid(function, &a, &b, &c, &d); - if (d & SSE2_EDX_MASK) - has_sse2 = 1; - else - has_sse2 = 0; - } - - return has_sse2; -#endif - return false; -} - - -void build_output_lut(struct curveType *trc, - uint16_t **output_gamma_lut, size_t *output_gamma_lut_length) -{ - if (trc->count == 0) { - *output_gamma_lut = build_linear_table(4096); - *output_gamma_lut_length = 4096; - } else if (trc->count == 1) { - float gamma = 1./u8Fixed8Number_to_float(trc->data[0]); - *output_gamma_lut = build_pow_table(gamma, 4096); - *output_gamma_lut_length = 4096; - } else { - *output_gamma_lut = invert_lut(trc->data, trc->count); - *output_gamma_lut_length = trc->count; - } - -} - -void qcms_profile_precache_output_transform(qcms_profile *profile) -{ - if (!profile->output_table_r) { - profile->output_table_r = precache_create(); - if (!compute_precache(profile->redTRC, profile->output_table_r->data)) { - precache_release(profile->output_table_r); - profile->output_table_r = NULL; - } - } - if (!profile->output_table_g) { - profile->output_table_g = precache_create(); - if (!compute_precache(profile->greenTRC, profile->output_table_g->data)) { - precache_release(profile->output_table_g); - profile->output_table_g = NULL; - } - } - if (!profile->output_table_b) { - profile->output_table_b = precache_create(); - if (!compute_precache(profile->blueTRC, profile->output_table_b->data)) { - precache_release(profile->output_table_g); - profile->output_table_g = NULL; - } - } -} - -#define NO_MEM_TRANSFORM NULL - -qcms_transform* qcms_transform_create( - qcms_profile *in, qcms_data_type in_type, - qcms_profile* out, qcms_data_type out_type, - qcms_intent intent) -{ - bool precache = false; - - qcms_transform *transform = calloc(sizeof(qcms_transform), 1); - if (!transform) { - return NULL; - } - if (out_type != QCMS_DATA_RGB_8 && - out_type != QCMS_DATA_RGBA_8) { - assert(0 && "output type"); - free(transform); - return NULL; - } - - if (out->output_table_r && - out->output_table_g && - out->output_table_b) { - precache = true; - } - - if (precache) { - transform->output_table_r = precache_reference(out->output_table_r); - transform->output_table_g = precache_reference(out->output_table_g); - transform->output_table_b = precache_reference(out->output_table_b); - } else { - build_output_lut(out->redTRC, &transform->output_gamma_lut_r, &transform->output_gamma_lut_r_length); - build_output_lut(out->greenTRC, &transform->output_gamma_lut_g, &transform->output_gamma_lut_g_length); - build_output_lut(out->blueTRC, &transform->output_gamma_lut_b, &transform->output_gamma_lut_b_length); - if (!transform->output_gamma_lut_r || !transform->output_gamma_lut_g || !transform->output_gamma_lut_b) { - qcms_transform_release(transform); - return NO_MEM_TRANSFORM; - } - } - - if (in->color_space == RGB_SIGNATURE) { - struct matrix in_matrix, out_matrix, result; - - if (in_type != QCMS_DATA_RGB_8 && - in_type != QCMS_DATA_RGBA_8){ - assert(0 && "input type"); - free(transform); - return NULL; - } - if (precache) { -#ifdef X86 - if (sse2_available()) { - if (in_type == QCMS_DATA_RGB_8) - transform->transform_fn = qcms_transform_data_rgb_out_lut_sse; - else - transform->transform_fn = qcms_transform_data_rgba_out_lut_sse; - - } else -#endif - { - if (in_type == QCMS_DATA_RGB_8) - transform->transform_fn = qcms_transform_data_rgb_out_lut_precache; - else - transform->transform_fn = qcms_transform_data_rgba_out_lut_precache; - } - } else { - if (in_type == QCMS_DATA_RGB_8) - transform->transform_fn = qcms_transform_data_rgb_out_lut; - else - transform->transform_fn = qcms_transform_data_rgba_out_lut; - } - - //XXX: avoid duplicating tables if we can - transform->input_gamma_table_r = build_input_gamma_table(in->redTRC); - transform->input_gamma_table_g = build_input_gamma_table(in->greenTRC); - transform->input_gamma_table_b = build_input_gamma_table(in->blueTRC); - - if (!transform->input_gamma_table_r || !transform->input_gamma_table_g || !transform->input_gamma_table_b) { - qcms_transform_release(transform); - return NO_MEM_TRANSFORM; - } - - /* build combined colorant matrix */ - in_matrix = build_colorant_matrix(in); - out_matrix = build_colorant_matrix(out); - out_matrix = matrix_invert(out_matrix); - if (out_matrix.invalid) { - qcms_transform_release(transform); - return NULL; - } - result = matrix_multiply(out_matrix, in_matrix); - - /* store the results in column major mode - * this makes doing the multiplication with sse easier */ - transform->matrix[0][0] = result.m[0][0]; - transform->matrix[1][0] = result.m[0][1]; - transform->matrix[2][0] = result.m[0][2]; - transform->matrix[0][1] = result.m[1][0]; - transform->matrix[1][1] = result.m[1][1]; - transform->matrix[2][1] = result.m[1][2]; - transform->matrix[0][2] = result.m[2][0]; - transform->matrix[1][2] = result.m[2][1]; - transform->matrix[2][2] = result.m[2][2]; - - } else if (in->color_space == GRAY_SIGNATURE) { - if (in_type != QCMS_DATA_GRAY_8 && - in_type != QCMS_DATA_GRAYA_8){ - assert(0 && "input type"); - free(transform); - return NULL; - } - - transform->input_gamma_table_gray = build_input_gamma_table(in->grayTRC); - if (!transform->input_gamma_table_gray) { - qcms_transform_release(transform); - return NO_MEM_TRANSFORM; - } - - if (precache) { - if (in_type == QCMS_DATA_GRAY_8) { - transform->transform_fn = qcms_transform_data_gray_out_precache; - } else { - transform->transform_fn = qcms_transform_data_graya_out_precache; - } - } else { - if (in_type == QCMS_DATA_GRAY_8) { - transform->transform_fn = qcms_transform_data_gray_out_lut; - } else { - transform->transform_fn = qcms_transform_data_graya_out_lut; - } - } - } else { - assert(0 && "unexpected colorspace"); - } - return transform; -} - -void qcms_transform_data(qcms_transform *transform, void *src, void *dest, size_t length) -{ - transform->transform_fn(transform, src, dest, length); -} diff --git a/gfx/src/thebes/Makefile.in b/gfx/src/thebes/Makefile.in index a29bca57526..62f41c90e5a 100644 --- a/gfx/src/thebes/Makefile.in +++ b/gfx/src/thebes/Makefile.in @@ -62,7 +62,6 @@ REQUIRES = xpcom \ unicharutil \ imglib2 \ $(ZLIB_REQUIRES) \ - qcms \ $(NULL) CPPSRCS = \ @@ -93,7 +92,6 @@ CPPSRCS += nsSystemFontsWin.cpp \ REQUIRES += \ cairo \ - qcms \ $(NULL) _OS_LIBS = usp10 diff --git a/gfx/thebes/public/gfxPlatform.h b/gfx/thebes/public/gfxPlatform.h index 9351fbc3b60..2f4eb0907b6 100644 --- a/gfx/thebes/public/gfxPlatform.h +++ b/gfx/thebes/public/gfxPlatform.h @@ -48,11 +48,13 @@ #include "gfxASurface.h" #include "gfxColor.h" -#include "qcms.h" #ifdef XP_OS2 #undef OS2EMX_PLAIN_CHAR #endif +typedef void* cmsHPROFILE; +typedef void* cmsHTRANSFORM; + class gfxImageSurface; class gfxFont; class gfxFontGroup; @@ -267,39 +269,39 @@ public: * * Sets 'out' to 'in' if transform is NULL. */ - static void TransformPixel(const gfxRGBA& in, gfxRGBA& out, qcms_transform *transform); + static void TransformPixel(const gfxRGBA& in, gfxRGBA& out, cmsHTRANSFORM transform); /** * Return the output device ICC profile. */ - static qcms_profile* GetCMSOutputProfile(); + static cmsHPROFILE GetCMSOutputProfile(); /** * Return the sRGB ICC profile. */ - static qcms_profile* GetCMSsRGBProfile(); + static cmsHPROFILE GetCMSsRGBProfile(); /** * Return sRGB -> output device transform. */ - static qcms_transform* GetCMSRGBTransform(); + static cmsHTRANSFORM GetCMSRGBTransform(); /** * Return output -> sRGB device transform. */ - static qcms_transform* GetCMSInverseRGBTransform(); + static cmsHTRANSFORM GetCMSInverseRGBTransform(); /** * Return sRGBA -> output device transform. */ - static qcms_transform* GetCMSRGBATransform(); + static cmsHTRANSFORM GetCMSRGBATransform(); protected: gfxPlatform() { } virtual ~gfxPlatform(); private: - virtual qcms_profile* GetPlatformCMSOutputProfile(); + virtual cmsHPROFILE GetPlatformCMSOutputProfile(); nsCOMPtr overrideObserver; }; diff --git a/gfx/thebes/public/gfxPlatformGtk.h b/gfx/thebes/public/gfxPlatformGtk.h index 2b5b429b1ae..eed910a5ccf 100644 --- a/gfx/thebes/public/gfxPlatformGtk.h +++ b/gfx/thebes/public/gfxPlatformGtk.h @@ -142,7 +142,7 @@ protected: static gfxFontconfigUtils *sFontconfigUtils; private: - virtual qcms_profile *GetPlatformCMSOutputProfile(); + virtual cmsHPROFILE GetPlatformCMSOutputProfile(); }; #endif /* GFX_PLATFORM_GTK_H */ diff --git a/gfx/thebes/public/gfxPlatformMac.h b/gfx/thebes/public/gfxPlatformMac.h index 742db1d10a6..77621b28b10 100644 --- a/gfx/thebes/public/gfxPlatformMac.h +++ b/gfx/thebes/public/gfxPlatformMac.h @@ -107,7 +107,7 @@ private: void AppendCJKPrefLangs(eFontPrefLang aPrefLangs[], PRUint32 &aLen, eFontPrefLang aCharLang, eFontPrefLang aPageLang); - virtual qcms_profile* GetPlatformCMSOutputProfile(); + virtual cmsHPROFILE GetPlatformCMSOutputProfile(); // read in the pref value for the lower threshold on font anti-aliasing static PRUint32 ReadAntiAliasingThreshold(); diff --git a/gfx/thebes/public/gfxQtPlatform.h b/gfx/thebes/public/gfxQtPlatform.h index c12f9e2f354..e602336b08e 100644 --- a/gfx/thebes/public/gfxQtPlatform.h +++ b/gfx/thebes/public/gfxQtPlatform.h @@ -97,7 +97,7 @@ protected: static gfxFontconfigUtils *sFontconfigUtils; private: - virtual qcms_profile *GetPlatformCMSOutputProfile(); + virtual cmsHPROFILE GetPlatformCMSOutputProfile(); }; #endif /* GFX_PLATFORM_QT_H */ diff --git a/gfx/thebes/public/gfxWindowsPlatform.h b/gfx/thebes/public/gfxWindowsPlatform.h index 4c0658244e6..11503cebe3e 100644 --- a/gfx/thebes/public/gfxWindowsPlatform.h +++ b/gfx/thebes/public/gfxWindowsPlatform.h @@ -163,7 +163,7 @@ private: nsRefPtr& aFontFamily, void* userArg); - virtual qcms_profile* GetPlatformCMSOutputProfile(); + virtual cmsHPROFILE GetPlatformCMSOutputProfile(); static int PrefChangedCallback(const char*, void*); diff --git a/gfx/thebes/src/Makefile.in b/gfx/thebes/src/Makefile.in index 0e46489f353..54c9e46a929 100644 --- a/gfx/thebes/src/Makefile.in +++ b/gfx/thebes/src/Makefile.in @@ -18,7 +18,6 @@ REQUIRES = \ xpcom \ unicharutil \ $(LCMS_REQUIRES) \ - qcms \ $(NULL) CPPSRCS = \ @@ -48,7 +47,7 @@ EXTRA_DSO_LDOPTS += \ $(XPCOM_LIBS) \ $(NSPR_LIBS) \ $(ZLIB_LIBS) \ - $(QCMS_LIBS) \ + $(LCMS_LIBS) \ $(NULL) diff --git a/gfx/thebes/src/gfxContext.cpp b/gfx/thebes/src/gfxContext.cpp index 75f6f8631c7..466f5c6cf2f 100644 --- a/gfx/thebes/src/gfxContext.cpp +++ b/gfx/thebes/src/gfxContext.cpp @@ -46,6 +46,7 @@ #endif #include "cairo.h" +#include "lcms.h" #include "gfxContext.h" diff --git a/gfx/thebes/src/gfxPattern.cpp b/gfx/thebes/src/gfxPattern.cpp index ca1e7ec1d91..d9eada746ed 100644 --- a/gfx/thebes/src/gfxPattern.cpp +++ b/gfx/thebes/src/gfxPattern.cpp @@ -41,6 +41,7 @@ #include "gfxPlatform.h" #include "cairo.h" +#include "lcms.h" gfxPattern::gfxPattern(cairo_pattern_t *aPattern) { diff --git a/gfx/thebes/src/gfxPlatform.cpp b/gfx/thebes/src/gfxPlatform.cpp index b3aded61bb0..7c3d6638f1e 100644 --- a/gfx/thebes/src/gfxPlatform.cpp +++ b/gfx/thebes/src/gfxPlatform.cpp @@ -65,7 +65,7 @@ #include "nsWeakReference.h" #include "cairo.h" -#include "qcms.h" +#include "lcms.h" #include "plstr.h" #include "nsIPrefService.h" @@ -75,12 +75,12 @@ gfxPlatform *gPlatform = nsnull; // These two may point to the same profile -static qcms_profile *gCMSOutputProfile = nsnull; -static qcms_profile *gCMSsRGBProfile = nsnull; +static cmsHPROFILE gCMSOutputProfile = nsnull; +static cmsHPROFILE gCMSsRGBProfile = nsnull; -static qcms_transform *gCMSRGBTransform = nsnull; -static qcms_transform *gCMSInverseRGBTransform = nsnull; -static qcms_transform *gCMSRGBATransform = nsnull; +static cmsHTRANSFORM gCMSRGBTransform = nsnull; +static cmsHTRANSFORM gCMSInverseRGBTransform = nsnull; +static cmsHTRANSFORM gCMSRGBATransform = nsnull; static PRBool gCMSInitialized = PR_FALSE; static eCMSMode gCMSMode = eCMSMode_Off; @@ -224,6 +224,16 @@ gfxPlatform::Init() if (prefs) prefs->AddObserver(CMForceSRGBPrefName, gPlatform->overrideObserver, PR_TRUE); + /* By default, LCMS calls exit() on error, which isn't what we want. If + cms is enabled, change the error functionality. */ + if (GetCMSMode() != eCMSMode_Off) { +#ifdef DEBUG + cmsErrorAction(LCMS_ERROR_SHOW); +#else + cmsErrorAction(LCMS_ERROR_IGNORE); +#endif + } + return NS_OK; } @@ -503,9 +513,7 @@ gfxPlatform::GetCMSMode() /* Chris Murphy (CM consultant) suggests this as a default in the event that we cannot reproduce relative + Black Point Compensation. BPC brings an unacceptable performance overhead, so we go with perceptual. */ -#define INTENT_DEFAULT QCMS_INTENT_PERCEPTUAL -#define INTENT_MIN 0 -#define INTENT_MAX 3 +#define INTENT_DEFAULT INTENT_PERCEPTUAL PRBool gfxPlatform::GetRenderingIntent() @@ -537,24 +545,20 @@ gfxPlatform::GetRenderingIntent() } void -gfxPlatform::TransformPixel(const gfxRGBA& in, gfxRGBA& out, qcms_transform *transform) +gfxPlatform::TransformPixel(const gfxRGBA& in, gfxRGBA& out, cmsHTRANSFORM transform) { if (transform) { - /* we want the bytes in RGB order */ #ifdef IS_LITTLE_ENDIAN - /* ABGR puts the bytes in |RGBA| order on little endian */ PRUint32 packed = in.Packed(gfxRGBA::PACKED_ABGR); - qcms_transform_data(transform, + cmsDoTransform(transform, (PRUint8 *)&packed, (PRUint8 *)&packed, 1); out.~gfxRGBA(); new (&out) gfxRGBA(packed, gfxRGBA::PACKED_ABGR); #else - /* ARGB puts the bytes in |ARGB| order on big endian */ PRUint32 packed = in.Packed(gfxRGBA::PACKED_ARGB); - /* add one to move past the alpha byte */ - qcms_transform_data(transform, + cmsDoTransform(transform, (PRUint8 *)&packed + 1, (PRUint8 *)&packed + 1, 1); out.~gfxRGBA(); @@ -566,13 +570,13 @@ gfxPlatform::TransformPixel(const gfxRGBA& in, gfxRGBA& out, qcms_transform *tra out = in; } -qcms_profile * +cmsHPROFILE gfxPlatform::GetPlatformCMSOutputProfile() { return nsnull; } -qcms_profile * +cmsHPROFILE gfxPlatform::GetCMSOutputProfile() { if (!gCMSOutputProfile) { @@ -598,7 +602,7 @@ gfxPlatform::GetCMSOutputProfile() rv = prefs->GetCharPref(CMProfilePrefName, getter_Copies(fname)); if (NS_SUCCEEDED(rv) && !fname.IsEmpty()) { - gCMSOutputProfile = qcms_profile_from_path(fname); + gCMSOutputProfile = cmsOpenProfileFromFile(fname, "r"); } } } @@ -610,87 +614,92 @@ gfxPlatform::GetCMSOutputProfile() /* Determine if the profile looks bogus. If so, close the profile * and use sRGB instead. See bug 460629, */ - if (gCMSOutputProfile && qcms_profile_is_bogus(gCMSOutputProfile)) { + if (gCMSOutputProfile && cmsProfileIsBogus(gCMSOutputProfile)) { NS_ASSERTION(gCMSOutputProfile != GetCMSsRGBProfile(), "Builtin sRGB profile tagged as bogus!!!"); - qcms_profile_release(gCMSOutputProfile); + cmsCloseProfile(gCMSOutputProfile); gCMSOutputProfile = nsnull; } if (!gCMSOutputProfile) { gCMSOutputProfile = GetCMSsRGBProfile(); } + /* Precache the LUT16 Interpolations for the output profile. See bug 444661 for details. */ - qcms_profile_precache_output_transform(gCMSOutputProfile); + cmsPrecacheProfile(gCMSOutputProfile, CMS_PRECACHE_LI168_REVERSE); } return gCMSOutputProfile; } -qcms_profile * +cmsHPROFILE gfxPlatform::GetCMSsRGBProfile() { if (!gCMSsRGBProfile) { /* Create the profile using lcms. */ - gCMSsRGBProfile = qcms_profile_sRGB(); + gCMSsRGBProfile = cmsCreate_sRGBProfile(); + + /* Precache the Fixed-point Interpolations for sRGB as an input + profile. See bug 444661 for details. */ + cmsPrecacheProfile(gCMSsRGBProfile, CMS_PRECACHE_LI8F_FORWARD); } return gCMSsRGBProfile; } -qcms_transform * +cmsHTRANSFORM gfxPlatform::GetCMSRGBTransform() { if (!gCMSRGBTransform) { - qcms_profile *inProfile, *outProfile; + cmsHPROFILE inProfile, outProfile; outProfile = GetCMSOutputProfile(); inProfile = GetCMSsRGBProfile(); if (!inProfile || !outProfile) return nsnull; - gCMSRGBTransform = qcms_transform_create(inProfile, QCMS_DATA_RGB_8, - outProfile, QCMS_DATA_RGB_8, - QCMS_INTENT_PERCEPTUAL); + gCMSRGBTransform = cmsCreateTransform(inProfile, TYPE_RGB_8, + outProfile, TYPE_RGB_8, + INTENT_PERCEPTUAL, cmsFLAGS_FLOATSHAPER); } return gCMSRGBTransform; } -qcms_transform * +cmsHTRANSFORM gfxPlatform::GetCMSInverseRGBTransform() { if (!gCMSInverseRGBTransform) { - qcms_profile *inProfile, *outProfile; + cmsHPROFILE inProfile, outProfile; inProfile = GetCMSOutputProfile(); outProfile = GetCMSsRGBProfile(); if (!inProfile || !outProfile) return nsnull; - gCMSInverseRGBTransform = qcms_transform_create(inProfile, QCMS_DATA_RGB_8, - outProfile, QCMS_DATA_RGB_8, - QCMS_INTENT_PERCEPTUAL); + gCMSInverseRGBTransform = cmsCreateTransform(inProfile, TYPE_RGB_8, + outProfile, TYPE_RGB_8, + INTENT_PERCEPTUAL, cmsFLAGS_FLOATSHAPER); } return gCMSInverseRGBTransform; } -qcms_transform * +cmsHTRANSFORM gfxPlatform::GetCMSRGBATransform() { if (!gCMSRGBATransform) { - qcms_profile *inProfile, *outProfile; + cmsHPROFILE inProfile, outProfile; outProfile = GetCMSOutputProfile(); inProfile = GetCMSsRGBProfile(); if (!inProfile || !outProfile) return nsnull; - gCMSRGBATransform = qcms_transform_create(inProfile, QCMS_DATA_RGBA_8, - outProfile, QCMS_DATA_RGBA_8, - QCMS_INTENT_PERCEPTUAL); + gCMSRGBATransform = cmsCreateTransform(inProfile, TYPE_RGBA_8, + outProfile, TYPE_RGBA_8, + INTENT_PERCEPTUAL, cmsFLAGS_FLOATSHAPER); } return gCMSRGBATransform; @@ -701,19 +710,19 @@ static void ShutdownCMS() { if (gCMSRGBTransform) { - qcms_transform_release(gCMSRGBTransform); + cmsDeleteTransform(gCMSRGBTransform); gCMSRGBTransform = nsnull; } if (gCMSInverseRGBTransform) { - qcms_transform_release(gCMSInverseRGBTransform); + cmsDeleteTransform(gCMSInverseRGBTransform); gCMSInverseRGBTransform = nsnull; } if (gCMSRGBATransform) { - qcms_transform_release(gCMSRGBATransform); + cmsDeleteTransform(gCMSRGBATransform); gCMSRGBATransform = nsnull; } if (gCMSOutputProfile) { - qcms_profile_release(gCMSOutputProfile); + cmsCloseProfile(gCMSOutputProfile); // handle the aliased case if (gCMSsRGBProfile == gCMSOutputProfile) @@ -721,7 +730,7 @@ static void ShutdownCMS() gCMSOutputProfile = nsnull; } if (gCMSsRGBProfile) { - qcms_profile_release(gCMSsRGBProfile); + cmsCloseProfile(gCMSsRGBProfile); gCMSsRGBProfile = nsnull; } diff --git a/gfx/thebes/src/gfxPlatformGtk.cpp b/gfx/thebes/src/gfxPlatformGtk.cpp index 64076331dc7..367aec1de4f 100644 --- a/gfx/thebes/src/gfxPlatformGtk.cpp +++ b/gfx/thebes/src/gfxPlatformGtk.cpp @@ -77,6 +77,8 @@ #include "nsMathUtils.h" +#include "lcms.h" + #define GDK_PIXMAP_SIZE_MAX 32767 #ifndef MOZ_PANGO @@ -527,7 +529,7 @@ gfxPlatformGtk::InitDPI() } } -qcms_profile * +cmsHPROFILE gfxPlatformGtk::GetPlatformCMSOutputProfile() { #ifdef MOZ_X11 @@ -557,10 +559,10 @@ gfxPlatformGtk::GetPlatformCMSOutputProfile() &retAtom, &retFormat, &retLength, &retAfter, &retProperty); - qcms_profile* profile = NULL; + cmsHPROFILE profile = NULL; if (retLength > 0) - profile = qcms_profile_from_memory(retProperty, retLength); + profile = cmsOpenProfileFromMem(retProperty, retLength); XFree(retProperty); @@ -582,8 +584,8 @@ gfxPlatformGtk::GetPlatformCMSOutputProfile() &retAtom, &retFormat, &retLength, &retAfter, &retProperty)) { double gamma; - qcms_CIE_xyY whitePoint; - qcms_CIE_xyYTRIPLE primaries; + cmsCIExyY whitePoint; + cmsCIExyYTRIPLE primaries; if (retLength != 128) { #ifdef DEBUG_tor @@ -601,23 +603,23 @@ gfxPlatformGtk::GetPlatformCMSOutputProfile() (retProperty[0x1a] >> 0 & 3)) / 1024.0; whitePoint.Y = 1.0; - primaries.red.x = ((retProperty[0x1b] << 2) | + primaries.Red.x = ((retProperty[0x1b] << 2) | (retProperty[0x19] >> 6 & 3)) / 1024.0; - primaries.red.y = ((retProperty[0x1c] << 2) | + primaries.Red.y = ((retProperty[0x1c] << 2) | (retProperty[0x19] >> 4 & 3)) / 1024.0; - primaries.red.Y = 1.0; + primaries.Red.Y = 1.0; - primaries.green.x = ((retProperty[0x1d] << 2) | + primaries.Green.x = ((retProperty[0x1d] << 2) | (retProperty[0x19] >> 2 & 3)) / 1024.0; - primaries.green.y = ((retProperty[0x1e] << 2) | + primaries.Green.y = ((retProperty[0x1e] << 2) | (retProperty[0x19] >> 0 & 3)) / 1024.0; - primaries.green.Y = 1.0; + primaries.Green.Y = 1.0; - primaries.blue.x = ((retProperty[0x1f] << 2) | + primaries.Blue.x = ((retProperty[0x1f] << 2) | (retProperty[0x1a] >> 6 & 3)) / 1024.0; - primaries.blue.y = ((retProperty[0x20] << 2) | + primaries.Blue.y = ((retProperty[0x20] << 2) | (retProperty[0x1a] >> 4 & 3)) / 1024.0; - primaries.blue.Y = 1.0; + primaries.Blue.Y = 1.0; XFree(retProperty); @@ -631,8 +633,17 @@ gfxPlatformGtk::GetPlatformCMSOutputProfile() primaries.Blue.x, primaries.Blue.y, primaries.Blue.Y); #endif - qcms_profile* profile = - qcms_profile_create_rgb_with_gamma(whitePoint, primaries, gamma); + LPGAMMATABLE gammaTable[3]; + gammaTable[0] = gammaTable[1] = gammaTable[2] = + cmsBuildGamma(256, gamma); + + if (!gammaTable[0]) + return nsnull; + + cmsHPROFILE profile = + cmsCreateRGBProfile(&whitePoint, &primaries, gammaTable); + + cmsFreeGamma(gammaTable[0]); #ifdef DEBUG_tor if (profile) { diff --git a/gfx/thebes/src/gfxPlatformMac.cpp b/gfx/thebes/src/gfxPlatformMac.cpp index f1d28f690b7..cbbc7bf9421 100644 --- a/gfx/thebes/src/gfxPlatformMac.cpp +++ b/gfx/thebes/src/gfxPlatformMac.cpp @@ -58,7 +58,7 @@ #include "nsTArray.h" #include "nsUnicodeRange.h" -#include "qcms.h" +#include "lcms.h" gfxPlatformMac::gfxPlatformMac() { @@ -382,7 +382,7 @@ gfxPlatformMac::ReadAntiAliasingThreshold() return threshold; } -qcms_profile * +cmsHPROFILE gfxPlatformMac::GetPlatformCMSOutputProfile() { CMProfileLocation device; @@ -393,14 +393,14 @@ gfxPlatformMac::GetPlatformCMSOutputProfile() if (err != noErr) return nsnull; - qcms_profile *profile = nsnull; + cmsHPROFILE profile = nsnull; switch (device.locType) { case cmFileBasedProfile: { FSRef fsRef; if (!FSpMakeFSRef(&device.u.fileLoc.spec, &fsRef)) { char path[512]; if (!FSRefMakePath(&fsRef, (UInt8*)(path), sizeof(path))) { - profile = qcms_profile_from_path(path); + profile = cmsOpenProfileFromFile(path, "r"); #ifdef DEBUG_tor if (profile) fprintf(stderr, @@ -411,7 +411,7 @@ gfxPlatformMac::GetPlatformCMSOutputProfile() break; } case cmPathBasedProfile: - profile = qcms_profile_from_path(device.u.pathLoc.path); + profile = cmsOpenProfileFromFile(device.u.pathLoc.path, "r"); #ifdef DEBUG_tor if (profile) fprintf(stderr, diff --git a/gfx/thebes/src/gfxQtPlatform.cpp b/gfx/thebes/src/gfxQtPlatform.cpp index 4a4443b6f71..92677b75221 100644 --- a/gfx/thebes/src/gfxQtPlatform.cpp +++ b/gfx/thebes/src/gfxQtPlatform.cpp @@ -59,7 +59,7 @@ #include "nsMathUtils.h" #include "nsTArray.h" -#include "qcms.h" +#include "lcms.h" #include #include FT_FREETYPE_H @@ -354,7 +354,7 @@ gfxQtPlatform::InitDPI() } } -qcms_profile* +cmsHPROFILE gfxQtPlatform::GetPlatformCMSOutputProfile() { return nsnull; diff --git a/gfx/thebes/src/gfxWindowsPlatform.cpp b/gfx/thebes/src/gfxWindowsPlatform.cpp index ae7362cc661..2291fb3a45d 100644 --- a/gfx/thebes/src/gfxWindowsPlatform.cpp +++ b/gfx/thebes/src/gfxWindowsPlatform.cpp @@ -70,6 +70,8 @@ #include +#include "lcms.h" + #ifdef MOZ_FT2_FONTS static FT_Library gPlatformFTLibrary = NULL; #endif @@ -827,7 +829,7 @@ gfxWindowsPlatform::FindFontEntry(const nsAString& aName, const gfxFontStyle& aF return ff->FindFontEntry(aFontStyle); } -qcms_profile* +cmsHPROFILE gfxWindowsPlatform::GetPlatformCMSOutputProfile() { #ifndef MOZ_FT2_FONTS @@ -838,8 +840,8 @@ gfxWindowsPlatform::GetPlatformCMSOutputProfile() GetICMProfileW(dc, &size, (LPWSTR)&str); ReleaseDC(nsnull, dc); - qcms_profile* profile = - qcms_profile_from_path(NS_ConvertUTF16toUTF8(str).get()); + cmsHPROFILE profile = + cmsOpenProfileFromFile(NS_ConvertUTF16toUTF8(str).get(), "r"); #ifdef DEBUG_tor if (profile) fprintf(stderr, diff --git a/gfx/thebes/test/Makefile.in b/gfx/thebes/test/Makefile.in index c46626724a7..6e728c897b0 100644 --- a/gfx/thebes/test/Makefile.in +++ b/gfx/thebes/test/Makefile.in @@ -51,10 +51,10 @@ REQUIRES = \ thebes \ cairo \ pref \ + lcms \ necko \ unicharutil \ nspr \ - qcms \ $(NULL) # All platforms @@ -63,8 +63,8 @@ CPPSRCS = \ gfxFontSelectionTest.cpp \ gfxTextRunPerfTest.cpp \ gfxWordCacheTest.cpp \ + gfxColorManagementTest.cpp \ $(NULL) -# gfxColorManagementTest.cpp \ ifeq ($(MOZ_WIDGET_TOOLKIT),cocoa) CMMSRCS = gfxTestCocoaHelper.mm @@ -86,6 +86,7 @@ LIBS = $(HELPER_OBJS) \ $(NSPR_LIBS) \ $(TK_LIBS) \ $(ZLIB_LIBS) \ + $(LCMS_LIBS) \ $(NULL) ifeq ($(MOZ_WIDGET_TOOLKIT),windows) diff --git a/layout/base/Makefile.in b/layout/base/Makefile.in index cc840919275..e5d075ecbf7 100644 --- a/layout/base/Makefile.in +++ b/layout/base/Makefile.in @@ -78,7 +78,6 @@ REQUIRES = xpcom \ shistory \ caps \ thebes \ - qcms \ $(NULL) ifdef ACCESSIBILITY diff --git a/layout/mathml/Makefile.in b/layout/mathml/Makefile.in index 18a7855faeb..8ba80d05a78 100644 --- a/layout/mathml/Makefile.in +++ b/layout/mathml/Makefile.in @@ -64,7 +64,6 @@ REQUIRES = xpcom \ webbrwsr \ pref \ js \ - qcms \ $(NULL) LOCAL_INCLUDES = \ diff --git a/layout/svg/base/src/Makefile.in b/layout/svg/base/src/Makefile.in index 716eb359368..cfb4723072e 100644 --- a/layout/svg/base/src/Makefile.in +++ b/layout/svg/base/src/Makefile.in @@ -63,7 +63,6 @@ REQUIRES = xpcom \ xpconnect \ docshell \ thebes \ - qcms \ $(NULL) CPPSRCS = \ diff --git a/modules/libpr0n/build/Makefile.in b/modules/libpr0n/build/Makefile.in index c1e851bcee6..799ebfc84a7 100644 --- a/modules/libpr0n/build/Makefile.in +++ b/modules/libpr0n/build/Makefile.in @@ -60,7 +60,7 @@ REQUIRES = xpcom \ $(JPEG_REQUIRES) \ $(PNG_REQUIRES) \ $(ZLIB_REQUIRES) \ - qcms \ + $(LCMS_REQUIRES) \ $(NULL) CPPSRCS = \ @@ -93,7 +93,7 @@ EXTRA_DSO_LDOPTS = \ $(LIBS_DIR) \ $(JPEG_LIBS) \ $(PNG_LIBS) $(ZLIB_LIBS) \ - $(QCMS_LIBS) \ + $(LCMS_LIBS) \ $(EXTRA_DSO_LIBS) \ $(MOZ_COMPONENT_LIBS) \ $(NULL) diff --git a/modules/libpr0n/decoders/gif/Makefile.in b/modules/libpr0n/decoders/gif/Makefile.in index 5cc3f1a7a7e..a7aadc9b019 100644 --- a/modules/libpr0n/decoders/gif/Makefile.in +++ b/modules/libpr0n/decoders/gif/Makefile.in @@ -53,7 +53,7 @@ REQUIRES = xpcom \ gfx \ thebes \ imglib2 \ - qcms \ + $(LCMS_REQUIRES) \ $(NULL) CPPSRCS = nsGIFDecoder2.cpp diff --git a/modules/libpr0n/decoders/gif/nsGIFDecoder2.cpp b/modules/libpr0n/decoders/gif/nsGIFDecoder2.cpp index 3ee3040b7bd..309882127f3 100644 --- a/modules/libpr0n/decoders/gif/nsGIFDecoder2.cpp +++ b/modules/libpr0n/decoders/gif/nsGIFDecoder2.cpp @@ -86,7 +86,7 @@ mailing address. #include "gfxColor.h" #include "gfxPlatform.h" -#include "qcms.h" +#include "lcms.h" /* * GETN(n, s) requests at least 'n' bytes available from 'q', at start of state 's' @@ -681,9 +681,9 @@ static void ConvertColormap(PRUint32 *aColormap, PRUint32 aColors) { // Apply CMS transformation if enabled and available if (gfxPlatform::GetCMSMode() == eCMSMode_All) { - qcms_transform *transform = gfxPlatform::GetCMSRGBTransform(); + cmsHTRANSFORM transform = gfxPlatform::GetCMSRGBTransform(); if (transform) - qcms_transform_data(transform, aColormap, aColormap, aColors); + cmsDoTransform(transform, aColormap, aColormap, aColors); } // Convert from the GIF's RGB format to the Cairo format. // Work from end to begin, because of the in-place expansion diff --git a/modules/libpr0n/decoders/jpeg/Makefile.in b/modules/libpr0n/decoders/jpeg/Makefile.in index 30c5ef054c4..76246da8e69 100644 --- a/modules/libpr0n/decoders/jpeg/Makefile.in +++ b/modules/libpr0n/decoders/jpeg/Makefile.in @@ -54,7 +54,7 @@ REQUIRES = xpcom \ thebes \ imglib2 \ $(JPEG_REQUIRES) \ - qcms \ + $(LCMS_REQUIRES) \ $(NULL) CPPSRCS = nsJPEGDecoder.cpp diff --git a/modules/libpr0n/decoders/jpeg/nsJPEGDecoder.cpp b/modules/libpr0n/decoders/jpeg/nsJPEGDecoder.cpp index cbb4696e674..c8610cf0e0c 100644 --- a/modules/libpr0n/decoders/jpeg/nsJPEGDecoder.cpp +++ b/modules/libpr0n/decoders/jpeg/nsJPEGDecoder.cpp @@ -125,9 +125,9 @@ nsJPEGDecoder::~nsJPEGDecoder() { PR_FREEIF(mBackBuffer); if (mTransform) - qcms_transform_release(mTransform); + cmsDeleteTransform(mTransform); if (mInProfile) - qcms_profile_release(mInProfile); + cmsCloseProfile(mInProfile); PR_LOG(gJPEGDecoderAccountingLog, PR_LOG_DEBUG, ("nsJPEGDecoder::~nsJPEGDecoder: Destroying JPEG decoder %p", @@ -338,10 +338,10 @@ nsresult nsJPEGDecoder::ProcessData(const char *data, PRUint32 count, PRUint32 * if ((cmsMode != eCMSMode_Off) && read_icc_profile(&mInfo, &profile, &profileLength) && - (mInProfile = qcms_profile_from_memory(profile, profileLength)) != NULL) { + (mInProfile = cmsOpenProfileFromMem(profile, profileLength)) != NULL) { free(profile); - PRUint32 profileSpace = qcms_profile_get_color_space(mInProfile); + PRUint32 profileSpace = cmsGetColorSpace(mInProfile); PRBool mismatch = PR_FALSE; #ifdef DEBUG_tor @@ -361,13 +361,14 @@ nsresult nsJPEGDecoder::ProcessData(const char *data, PRUint32 count, PRUint32 * case JCS_YCbCr: if (profileSpace == icSigRgbData) mInfo.out_color_space = JCS_RGB; - else - // qcms doesn't support ycbcr + else if (profileSpace != icSigYCbCrData) mismatch = PR_TRUE; break; case JCS_CMYK: case JCS_YCCK: - // qcms doesn't support cmyk + if (profileSpace == icSigCmykData) + mInfo.out_color_space = JCS_CMYK; + else mismatch = PR_TRUE; break; default: @@ -378,13 +379,19 @@ nsresult nsJPEGDecoder::ProcessData(const char *data, PRUint32 count, PRUint32 * } if (!mismatch) { - qcms_data_type type; + PRUint32 type; switch (mInfo.out_color_space) { case JCS_GRAYSCALE: - type = QCMS_DATA_GRAY_8; + type = COLORSPACE_SH(PT_GRAY) | CHANNELS_SH(1) | BYTES_SH(1); break; case JCS_RGB: - type = QCMS_DATA_RGB_8; + type = COLORSPACE_SH(PT_RGB) | CHANNELS_SH(3) | BYTES_SH(1); + break; + case JCS_YCbCr: + type = COLORSPACE_SH(PT_YCbCr) | CHANNELS_SH(3) | BYTES_SH(1); + break; + case JCS_CMYK: + type = COLORSPACE_SH(PT_CMYK) | CHANNELS_SH(4) | BYTES_SH(1); break; default: mState = JPEG_ERROR; @@ -392,28 +399,26 @@ nsresult nsJPEGDecoder::ProcessData(const char *data, PRUint32 count, PRUint32 * ("} (unknown colorpsace (2))")); return NS_ERROR_UNEXPECTED; } -#if 0 - We don't currently support CMYK profiles. The following - code dealt with lcms types. Add something like this - back when we gain support for CMYK. + /* Adobe Photoshop writes YCCK/CMYK files with inverted data */ if (mInfo.out_color_space == JCS_CMYK) type |= FLAVOR_SH(mInfo.saw_Adobe_marker ? 1 : 0); -#endif + if (gfxPlatform::GetCMSOutputProfile()) { /* Calculate rendering intent. */ int intent = gfxPlatform::GetRenderingIntent(); if (intent == -1) - intent = qcms_profile_get_rendering_intent(mInProfile); + intent = cmsTakeRenderingIntent(mInProfile); /* Create the color management transform. */ - mTransform = qcms_transform_create(mInProfile, + mTransform = cmsCreateTransform(mInProfile, type, gfxPlatform::GetCMSOutputProfile(), - QCMS_DATA_RGB_8, - (qcms_intent)intent); + TYPE_RGB_8, + intent, + cmsFLAGS_FLOATSHAPER); } } else { #ifdef DEBUG_tor @@ -741,7 +746,7 @@ nsJPEGDecoder::OutputScanlines(PRBool* suspend) to the 3byte RGB byte pixels at 'end' of row */ sampleRow += mInfo.output_width; } - qcms_transform_data(mTransform, source, sampleRow, mInfo.output_width); + cmsDoTransform(mTransform, source, sampleRow, mInfo.output_width); /* Move 3byte RGB data to end of row */ if (mInfo.out_color_space == JCS_CMYK) { memmove(sampleRow + mInfo.output_width, @@ -759,9 +764,9 @@ nsJPEGDecoder::OutputScanlines(PRBool* suspend) } if (gfxPlatform::GetCMSMode() == eCMSMode_All) { /* No embedded ICC profile - treat as sRGB */ - qcms_transform *transform = gfxPlatform::GetCMSRGBTransform(); + cmsHTRANSFORM transform = gfxPlatform::GetCMSRGBTransform(); if (transform) { - qcms_transform_data(transform, sampleRow, sampleRow, mInfo.output_width); + cmsDoTransform(transform, sampleRow, sampleRow, mInfo.output_width); } } } diff --git a/modules/libpr0n/decoders/jpeg/nsJPEGDecoder.h b/modules/libpr0n/decoders/jpeg/nsJPEGDecoder.h index 7b066ea49bb..9ec00c27379 100644 --- a/modules/libpr0n/decoders/jpeg/nsJPEGDecoder.h +++ b/modules/libpr0n/decoders/jpeg/nsJPEGDecoder.h @@ -50,7 +50,7 @@ #include "imgILoad.h" #include "nsIInputStream.h" #include "nsIPipe.h" -#include "qcms.h" +#include "lcms.h" extern "C" { #include "jpeglib.h" @@ -122,8 +122,8 @@ public: JOCTET *mProfile; PRUint32 mProfileLength; - qcms_profile *mInProfile; - qcms_transform *mTransform; + cmsHPROFILE mInProfile; + cmsHTRANSFORM mTransform; PRPackedBool mReading; }; diff --git a/modules/libpr0n/decoders/png/Makefile.in b/modules/libpr0n/decoders/png/Makefile.in index cbdd482b4b0..b0dd0ccbb9b 100644 --- a/modules/libpr0n/decoders/png/Makefile.in +++ b/modules/libpr0n/decoders/png/Makefile.in @@ -57,7 +57,7 @@ REQUIRES = xpcom \ imglib2 \ $(PNG_REQUIRES) \ $(ZLIB_REQUIRES) \ - qcms \ + $(LCMS_REQUIRES) \ $(NULL) CPPSRCS = nsPNGDecoder.cpp diff --git a/modules/libpr0n/decoders/png/nsPNGDecoder.cpp b/modules/libpr0n/decoders/png/nsPNGDecoder.cpp index 6b73f02a0fd..d5b5ddec0c1 100644 --- a/modules/libpr0n/decoders/png/nsPNGDecoder.cpp +++ b/modules/libpr0n/decoders/png/nsPNGDecoder.cpp @@ -89,11 +89,11 @@ nsPNGDecoder::~nsPNGDecoder() if (interlacebuf) nsMemory::Free(interlacebuf); if (mInProfile) { - qcms_profile_release(mInProfile); + cmsCloseProfile(mInProfile); /* mTransform belongs to us only if mInProfile is non-null */ if (mTransform) - qcms_transform_release(mTransform); + cmsDeleteTransform(mTransform); } } @@ -397,12 +397,12 @@ PNGDoGammaCorrection(png_structp png_ptr, png_infop info_ptr) } // Adapted from http://www.littlecms.com/pngchrm.c example code -static qcms_profile * +static cmsHPROFILE PNGGetColorProfile(png_structp png_ptr, png_infop info_ptr, - int color_type, qcms_data_type *inType, PRUint32 *intent) + int color_type, PRUint32 *inType, PRUint32 *intent) { - qcms_profile *profile = nsnull; - *intent = QCMS_INTENT_PERCEPTUAL; // Our default + cmsHPROFILE profile = nsnull; + *intent = INTENT_PERCEPTUAL; // Our default // First try to see if iCCP chunk is present if (png_get_valid(png_ptr, info_ptr, PNG_INFO_iCCP)) { @@ -413,40 +413,38 @@ PNGGetColorProfile(png_structp png_ptr, png_infop info_ptr, png_get_iCCP(png_ptr, info_ptr, &profileName, &compression, &profileData, &profileLen); - profile = qcms_profile_from_memory(profileData, profileLen); - if (profile) { - PRUint32 profileSpace = qcms_profile_get_color_space(profile); + profile = cmsOpenProfileFromMem(profileData, profileLen); + PRUint32 profileSpace = cmsGetColorSpace(profile); - PRBool mismatch = PR_FALSE; - if (color_type & PNG_COLOR_MASK_COLOR) { - if (profileSpace != icSigRgbData) - mismatch = PR_TRUE; - } else { - if (profileSpace == icSigRgbData) - png_set_gray_to_rgb(png_ptr); - else if (profileSpace != icSigGrayData) - mismatch = PR_TRUE; - } + PRBool mismatch = PR_FALSE; + if (color_type & PNG_COLOR_MASK_COLOR) { + if (profileSpace != icSigRgbData) + mismatch = PR_TRUE; + } else { + if (profileSpace == icSigRgbData) + png_set_gray_to_rgb(png_ptr); + else if (profileSpace != icSigGrayData) + mismatch = PR_TRUE; + } - if (mismatch) { - qcms_profile_release(profile); - profile = nsnull; - } else { - *intent = qcms_profile_get_rendering_intent(profile); - } + if (mismatch) { + cmsCloseProfile(profile); + profile = nsnull; + } else { + *intent = cmsTakeRenderingIntent(profile); } } // Check sRGB chunk if (!profile && png_get_valid(png_ptr, info_ptr, PNG_INFO_sRGB)) { - profile = qcms_profile_sRGB(); + profile = cmsCreate_sRGBProfile(); if (profile) { int fileIntent; png_set_gray_to_rgb(png_ptr); png_get_sRGB(png_ptr, info_ptr, &fileIntent); - PRUint32 map[] = { QCMS_INTENT_PERCEPTUAL, QCMS_INTENT_RELATIVE_COLORIMETRIC, - QCMS_INTENT_SATURATION, QCMS_INTENT_ABSOLUTE_COLORIMETRIC }; + PRUint32 map[] = { INTENT_PERCEPTUAL, INTENT_RELATIVE_COLORIMETRIC, + INTENT_SATURATION, INTENT_ABSOLUTE_COLORIMETRIC }; *intent = map[fileIntent]; } } @@ -455,40 +453,49 @@ PNGGetColorProfile(png_structp png_ptr, png_infop info_ptr, if (!profile && png_get_valid(png_ptr, info_ptr, PNG_INFO_gAMA) && png_get_valid(png_ptr, info_ptr, PNG_INFO_cHRM)) { - qcms_CIE_xyYTRIPLE primaries; - qcms_CIE_xyY whitePoint; + cmsCIExyYTRIPLE primaries; + cmsCIExyY whitePoint; png_get_cHRM(png_ptr, info_ptr, &whitePoint.x, &whitePoint.y, - &primaries.red.x, &primaries.red.y, - &primaries.green.x, &primaries.green.y, - &primaries.blue.x, &primaries.blue.y); + &primaries.Red.x, &primaries.Red.y, + &primaries.Green.x, &primaries.Green.y, + &primaries.Blue.x, &primaries.Blue.y); whitePoint.Y = - primaries.red.Y = primaries.green.Y = primaries.blue.Y = 1.0; + primaries.Red.Y = primaries.Green.Y = primaries.Blue.Y = 1.0; double gammaOfFile; + LPGAMMATABLE gammaTable[3]; png_get_gAMA(png_ptr, info_ptr, &gammaOfFile); - profile = qcms_profile_create_rgb_with_gamma(whitePoint, primaries, 1/gammaOfFile); + gammaTable[0] = gammaTable[1] = gammaTable[2] = + cmsBuildGamma(256, 1/gammaOfFile); + + if (!gammaTable[0]) + return nsnull; + + profile = cmsCreateRGBProfile(&whitePoint, &primaries, gammaTable); if (profile) png_set_gray_to_rgb(png_ptr); + + cmsFreeGamma(gammaTable[0]); } if (profile) { - PRUint32 profileSpace = qcms_profile_get_color_space(profile); + PRUint32 profileSpace = cmsGetColorSpace(profile); if (profileSpace == icSigGrayData) { if (color_type & PNG_COLOR_MASK_ALPHA) - *inType = QCMS_DATA_GRAYA_8; + *inType = TYPE_GRAYA_8; else - *inType = QCMS_DATA_GRAY_8; + *inType = TYPE_GRAY_8; } else { if (color_type & PNG_COLOR_MASK_ALPHA || png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) - *inType = QCMS_DATA_RGBA_8; + *inType = TYPE_RGBA_8; else - *inType = QCMS_DATA_RGB_8; + *inType = TYPE_RGB_8; } } @@ -549,8 +556,7 @@ info_callback(png_structp png_ptr, png_infop info_ptr) if (bit_depth == 16) png_set_strip_16(png_ptr); - qcms_data_type inType; - PRUint32 intent, pIntent; + PRUint32 inType, intent, pIntent; if (gfxPlatform::GetCMSMode() != eCMSMode_Off) { intent = gfxPlatform::GetRenderingIntent(); decoder->mInProfile = PNGGetColorProfile(png_ptr, info_ptr, @@ -560,19 +566,25 @@ info_callback(png_structp png_ptr, png_infop info_ptr) intent = pIntent; } if (decoder->mInProfile && gfxPlatform::GetCMSOutputProfile()) { - qcms_data_type outType; + PRUint32 outType; PRUint32 dwFlags = 0; if (color_type & PNG_COLOR_MASK_ALPHA || num_trans) - outType = QCMS_DATA_RGBA_8; + outType = TYPE_RGBA_8; else - outType = QCMS_DATA_RGB_8; + outType = TYPE_RGB_8; - decoder->mTransform = qcms_transform_create(decoder->mInProfile, + /* Determine if we can use the optimized floating point path. */ + if ((inType == outType) && + ((inType == TYPE_RGB_8) || (inType == TYPE_RGBA_8))) + dwFlags |= cmsFLAGS_FLOATSHAPER; + + decoder->mTransform = cmsCreateTransform(decoder->mInProfile, inType, gfxPlatform::GetCMSOutputProfile(), outType, - (qcms_intent)intent); + intent, + dwFlags); } else { png_set_gray_to_rgb(png_ptr); PNGDoGammaCorrection(png_ptr, info_ptr); @@ -737,7 +749,7 @@ row_callback(png_structp png_ptr, png_bytep new_row, if (decoder->mTransform) { if (decoder->mCMSLine) { - qcms_transform_data(decoder->mTransform, line, decoder->mCMSLine, iwidth); + cmsDoTransform(decoder->mTransform, line, decoder->mCMSLine, iwidth); /* copy alpha over */ PRUint32 channels = decoder->mChannels; if (channels == 2 || channels == 4) { @@ -746,7 +758,7 @@ row_callback(png_structp png_ptr, png_bytep new_row, } line = decoder->mCMSLine; } else { - qcms_transform_data(decoder->mTransform, line, line, iwidth); + cmsDoTransform(decoder->mTransform, line, line, iwidth); } } diff --git a/modules/libpr0n/decoders/png/nsPNGDecoder.h b/modules/libpr0n/decoders/png/nsPNGDecoder.h index e5b27433d88..1a3268e0c52 100644 --- a/modules/libpr0n/decoders/png/nsPNGDecoder.h +++ b/modules/libpr0n/decoders/png/nsPNGDecoder.h @@ -52,7 +52,7 @@ #include "png.h" -#include "qcms.h" +#include "lcms.h" #define NS_PNGDECODER_CID \ { /* 36fa00c2-1dd2-11b2-be07-d16eeb4c50ed */ \ @@ -87,8 +87,8 @@ public: png_infop mInfo; PRUint8 *mCMSLine; PRUint8 *interlacebuf; - qcms_profile *mInProfile; - qcms_transform *mTransform; + cmsHPROFILE mInProfile; + cmsHTRANSFORM mTransform; gfx_format format; PRUint8 mChannels; diff --git a/modules/libpr0n/test/reftest/pngsuite-ancillary/ccwn2c08.html b/modules/libpr0n/test/reftest/pngsuite-ancillary/ccwn2c08.html index 2d3972e9bcc..31834e5074e 100644 --- a/modules/libpr0n/test/reftest/pngsuite-ancillary/ccwn2c08.html +++ b/modules/libpr0n/test/reftest/pngsuite-ancillary/ccwn2c08.html @@ -1,4 +1,8 @@ - + + + + + @@ -78,10 +82,10 @@ - - + + - + @@ -111,13 +115,13 @@ - + - + - + @@ -146,14 +150,14 @@ - + - + - + - + @@ -176,15 +180,15 @@ - - + + - + - + - + @@ -212,18 +216,24 @@ - + - + - + - + - + @@ -243,22 +253,22 @@ - - + + - + - + - - + + - + @@ -282,16 +292,16 @@ - + - + - + @@ -313,22 +323,22 @@ - + - - - - + + + + - + - + @@ -345,12 +355,12 @@ - + - - + + @@ -358,11 +368,11 @@ - + - - - + + + @@ -382,22 +392,28 @@ - - - + + + - + - - + + - - - + + + @@ -411,28 +427,34 @@ - - - + + + - - + + - - - + + + - - + + - + - - + + @@ -445,27 +467,27 @@ - - - - - - + + + + + + - - + + - + - + - + @@ -483,26 +505,26 @@ - + - - - + + + - + - - + + - - + + - - + + @@ -514,28 +536,28 @@ - + - - + + - + - + - + - + @@ -549,19 +571,19 @@ - + - + - - - - - - - - + + + + + + + + @@ -571,8 +593,8 @@ - - + + @@ -580,59 +602,59 @@ - - - - + + + + - - - - - - - + + + + + + + - - + + - + - - - + + + - + - + - - + + - + - + - - - - + + + + - - - - + + + + - + @@ -642,205 +664,205 @@ - + - - - + + + - + - - + + - + - + - + - + - + - + - - - - + + + + - - - - - - - + + + + + + + - + - - - - + + + + - + - + - + - + - - + + - - + + - + - + - - - + + + - - + + - - + + - + - + - + - + - - + + - + - - + + - - + + - + - + - - + + - - - + + + - - - + + + - - - - - + + + + + - - + + - - + + - - - - - + + + + + - + - - + + - + - - + + - + - + - + - - - - - - + + + + + + @@ -851,7 +873,7 @@ - + @@ -859,21 +881,21 @@ - + - + - + - + - - - + + + @@ -885,25 +907,25 @@ - + - + - - + + - + - + @@ -919,24 +941,24 @@ - - + + - - - - + + + + - - + + @@ -953,20 +975,20 @@ - + - + - - - + + + - + - + @@ -988,18 +1010,18 @@ - + - - - - + + + + - + - + @@ -1024,13 +1046,13 @@ - - + + - + - - + + @@ -1089,4 +1111,4 @@
- \ No newline at end of file + diff --git a/modules/libpr0n/test/reftest/pngsuite-ancillary/ccwn3p08.html b/modules/libpr0n/test/reftest/pngsuite-ancillary/ccwn3p08.html index 94d08ef047f..fa7d9114115 100644 --- a/modules/libpr0n/test/reftest/pngsuite-ancillary/ccwn3p08.html +++ b/modules/libpr0n/test/reftest/pngsuite-ancillary/ccwn3p08.html @@ -1,4 +1,8 @@ - + + + + + @@ -82,7 +86,7 @@ - + @@ -110,11 +114,11 @@ - + - - + + @@ -143,16 +147,16 @@ - - - - + + + + - + - + @@ -180,15 +184,21 @@ - + - + - + @@ -219,9 +229,16 @@ - - - + + @@ -243,7 +260,7 @@ - + @@ -253,9 +270,15 @@ - - - + + + @@ -288,10 +311,10 @@ - + - - + + @@ -315,8 +338,8 @@ - - + + @@ -348,13 +371,13 @@ - - + + - + @@ -378,26 +401,26 @@ - - + + - - - + + + - - - + + + - - + + - + @@ -411,28 +434,28 @@ - - - + + + - - - - + + + + - - + + - - + + - + @@ -445,28 +468,28 @@ - - + + - + - + - + - - + + - + - + - - + + @@ -480,29 +503,29 @@ - + - + - - - + + + - + - + - - + + - + @@ -513,31 +536,31 @@ - + - + - - - + + + - - - + + + - - + + - + @@ -546,33 +569,33 @@ - - + + - + - + - - + + - + - - - + + + - - - + + + - + @@ -581,28 +604,28 @@ - - - + + + - - - - + + + + - + - - - - + + + + @@ -614,35 +637,35 @@ - + - - + + - - - - + + + + - + - - + + - + @@ -650,91 +673,91 @@ - - - + + + - - - - - - - - - + + + + + + + + + - + - - + + - + - - - + + + - - - - - + + + + + - - - + + + - - - - + + + + - - - - - - + + + + + + - + - + - + - - - - + + + + - - - + + + - + - + - - + + @@ -743,14 +766,14 @@ - - - + + + - + @@ -759,23 +782,23 @@ - - + + - - - - + + + + - + - - + + @@ -784,8 +807,8 @@ - - + + @@ -793,24 +816,24 @@ - - - - + + + + - + - + - - - - - + + + + + @@ -818,28 +841,28 @@ - - + + - + - - - - + + + + - - - - - + + + + + @@ -852,28 +875,35 @@ - - + - - - + + + - - - - - - - - - - + + + + + + + + + + @@ -889,22 +919,22 @@ - + - - - - - - - - + + + + + + + + - + @@ -928,15 +958,15 @@ - - + + - - - - - - + + + + + + @@ -953,7 +983,7 @@ - + @@ -963,11 +993,11 @@ - - - - - + + + + + @@ -994,12 +1024,12 @@ - - - - - - + + + + + + @@ -1023,14 +1053,14 @@ - - - - - - - - + + + + + + + + @@ -1089,4 +1119,4 @@
- \ No newline at end of file + diff --git a/toolkit/library/libxul-rules.mk b/toolkit/library/libxul-rules.mk index 5152478a36e..299c22c6136 100644 --- a/toolkit/library/libxul-rules.mk +++ b/toolkit/library/libxul-rules.mk @@ -40,7 +40,7 @@ EXTRA_DSO_LDOPTS += \ $(LIBS_DIR) \ $(JPEG_LIBS) \ $(PNG_LIBS) \ - $(QCMS_LIBS) \ + $(LCMS_LIBS) \ $(MOZ_JS_LIBS) \ $(NSS_LIBS) \ $(MOZ_CAIRO_LIBS) \ diff --git a/toolkit/toolkit-makefiles.sh b/toolkit/toolkit-makefiles.sh index 5869cf2fc0a..7e7646c4ad6 100644 --- a/toolkit/toolkit-makefiles.sh +++ b/toolkit/toolkit-makefiles.sh @@ -755,8 +755,10 @@ MAKEFILES_libmar=" modules/libmar/tool/Makefile " -MAKEFILES_qcms=" - modules/qcms/Makefile +MAKEFILES_lcms=" + modules/lcms/Makefile + modules/lcms/include/Makefile + modules/lcms/src/Makefile " add_makefiles " @@ -802,7 +804,6 @@ add_makefiles " $MAKEFILES_zlib $MAKEFILES_libmar $MAKEFILES_lcms - $MAKEFILES_qcms " # diff --git a/toolkit/toolkit-tiers.mk b/toolkit/toolkit-tiers.mk index 24fed742fa7..a4dd4037c4d 100644 --- a/toolkit/toolkit-tiers.mk +++ b/toolkit/toolkit-tiers.mk @@ -70,7 +70,7 @@ endif tier_external_dirs += modules/libmar endif -tier_external_dirs += gfx/qcms +tier_external_dirs += modules/lcms # # tier "gecko" - core components diff --git a/widget/src/build/Makefile.in b/widget/src/build/Makefile.in index b35c058d6b3..8fe7feb8d8f 100644 --- a/widget/src/build/Makefile.in +++ b/widget/src/build/Makefile.in @@ -90,7 +90,7 @@ EXTRA_DSO_LDOPTS = \ $(EXTRA_DSO_LIBS) \ $(MOZ_COMPONENT_LIBS) \ $(MOZ_UNICHARUTIL_LIBS) \ - $(QCMS_LIBS) + $(LCMS_LIBS) \ $(NULL) include $(topsrcdir)/config/rules.mk diff --git a/widget/src/cocoa/Makefile.in b/widget/src/cocoa/Makefile.in index da463aabbee..e38a871e948 100644 --- a/widget/src/cocoa/Makefile.in +++ b/widget/src/cocoa/Makefile.in @@ -66,7 +66,7 @@ REQUIRES = xpcom \ intl \ exthandler \ appshell \ - qcms \ + lcms \ thebes \ js \ xpconnect \ @@ -125,7 +125,7 @@ EXTRA_DSO_LDOPTS += \ $(call EXPAND_LIBNAME_PATH,gkgfx,$(DEPTH)/gfx/src) \ $(MOZ_COMPONENT_LIBS) \ -lthebes \ - $(QCMS_LIBS) \ + $(LCMS_LIBS) \ $(NULL) include $(topsrcdir)/config/rules.mk diff --git a/widget/src/cocoa/nsCocoaWindow.mm b/widget/src/cocoa/nsCocoaWindow.mm index 0d7e151fd14..3be9c46c68f 100644 --- a/widget/src/cocoa/nsCocoaWindow.mm +++ b/widget/src/cocoa/nsCocoaWindow.mm @@ -64,7 +64,7 @@ #include "nsNativeThemeColors.h" #include "gfxPlatform.h" -#include "qcms.h" +#include "lcms.h" // defined in nsAppShell.mm extern nsCocoaAppModalWindowList *gCocoaAppModalWindowList; @@ -1354,13 +1354,13 @@ NS_IMETHODIMP nsCocoaWindow::SetWindowTitlebarColor(nscolor aColor, PRBool aActi // to match the system appearance lame, so probably we just shouldn't color // correct chrome. if (gfxPlatform::GetCMSMode() == eCMSMode_All) { - qcms_transform *transform = gfxPlatform::GetCMSRGBATransform(); + cmsHTRANSFORM transform = gfxPlatform::GetCMSRGBATransform(); if (transform) { PRUint8 color[3]; color[0] = NS_GET_R(aColor); color[1] = NS_GET_G(aColor); color[2] = NS_GET_B(aColor); - qcms_transform_data(transform, color, color, 1); + cmsDoTransform(transform, color, color, 1); aColor = NS_RGB(color[0], color[1], color[2]); } } diff --git a/widget/src/gtk2/Makefile.in b/widget/src/gtk2/Makefile.in index 3cd6f244f25..25d9f3744f8 100644 --- a/widget/src/gtk2/Makefile.in +++ b/widget/src/gtk2/Makefile.in @@ -69,7 +69,6 @@ REQUIRES = xpcom \ locale \ thebes \ cairo \ - qcms \ $(NULL) ifdef MOZ_X11 @@ -143,7 +142,7 @@ EXTRA_DSO_LDOPTS += \ $(XCOMPOSITE_LIBS) \ $(MOZ_GTK2_LIBS) \ -lthebes \ - $(QCMS_LIBS) \ + $(LCMS_LIBS) \ $(NULL) ifdef MOZ_PLATFORM_HILDON diff --git a/widget/src/os2/Makefile.in b/widget/src/os2/Makefile.in index 8ecbf6e3d4c..d1490e56851 100644 --- a/widget/src/os2/Makefile.in +++ b/widget/src/os2/Makefile.in @@ -107,7 +107,7 @@ EXTRA_DSO_LDOPTS = \ $(MOZ_UNICHARUTIL_LIBS) \ $(MOZ_COMPONENT_LIBS) \ -lthebes \ - $(QCMS_LIBS) \ + $(LCMS_LIBS) \ $(NULL) ifdef ENABLE_TESTS diff --git a/widget/src/qt/Makefile.in b/widget/src/qt/Makefile.in index 2a677e54081..5e53f0c0a09 100644 --- a/widget/src/qt/Makefile.in +++ b/widget/src/qt/Makefile.in @@ -106,10 +106,10 @@ EXTRA_DSO_LDOPTS = \ $(MOZ_COMPONENT_LIBS) \ -lgkgfx \ -lthebes \ + $(LCMS_LIBS) \ $(MOZ_JS_LIBS) \ $(MOZ_QT_LIBS) \ $(GLIB_LIBS) \ - $(QCMS_LIBS) \ $(NULL) diff --git a/widget/src/windows/Makefile.in b/widget/src/windows/Makefile.in index 356f8f7959e..533cf4e7c88 100644 --- a/widget/src/windows/Makefile.in +++ b/widget/src/windows/Makefile.in @@ -71,7 +71,6 @@ REQUIRES = xpcom \ unicharutil \ thebes \ cairo \ - qcms \ $(NULL) CPPSRCS = \ diff --git a/widget/src/xpwidgets/Makefile.in b/widget/src/xpwidgets/Makefile.in index 8b5bde643cd..898a8f5fe6a 100644 --- a/widget/src/xpwidgets/Makefile.in +++ b/widget/src/xpwidgets/Makefile.in @@ -61,7 +61,7 @@ REQUIRES = xpcom \ unicharutil \ view \ windowwatcher \ - qcms \ + lcms \ thebes \ $(NULL) diff --git a/widget/src/xpwidgets/nsXPLookAndFeel.cpp b/widget/src/xpwidgets/nsXPLookAndFeel.cpp index e0a0da80b22..1f8154b45fa 100644 --- a/widget/src/xpwidgets/nsXPLookAndFeel.cpp +++ b/widget/src/xpwidgets/nsXPLookAndFeel.cpp @@ -47,7 +47,7 @@ #include "nsFont.h" #include "gfxPlatform.h" -#include "qcms.h" +#include "lcms.h" #ifdef DEBUG #include "nsSize.h" @@ -632,13 +632,13 @@ nsXPLookAndFeel::GetColor(const nsColorID aID, nscolor &aColor) if (sUseNativeColors && NS_SUCCEEDED(NativeGetColor(aID, aColor))) { if ((gfxPlatform::GetCMSMode() == eCMSMode_All) && !IsSpecialColor(aID, aColor)) { - qcms_transform *transform = gfxPlatform::GetCMSInverseRGBTransform(); + cmsHTRANSFORM transform = gfxPlatform::GetCMSInverseRGBTransform(); if (transform) { PRUint8 color[3]; color[0] = NS_GET_R(aColor); color[1] = NS_GET_G(aColor); color[2] = NS_GET_B(aColor); - qcms_transform_data(transform, color, color, 1); + cmsDoTransform(transform, color, color, 1); aColor = NS_RGB(color[0], color[1], color[2]); } }