gfx/qcms/qcmsint.h

Tue, 06 Jan 2015 21:39:09 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Tue, 06 Jan 2015 21:39:09 +0100
branch
TOR_BUG_9701
changeset 8
97036ab72558
permissions
-rw-r--r--

Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.

     1 /* vim: set ts=8 sw=8 noexpandtab: */
     2 #include "qcms.h"
     3 #include "qcmstypes.h"
     5 /* used as a lookup table for the output transformation.
     6  * we refcount them so we only need to have one around per output
     7  * profile, instead of duplicating them per transform */
     8 struct precache_output
     9 {
    10 	int ref_count;
    11 	/* We previously used a count of 65536 here but that seems like more
    12 	 * precision than we actually need.  By reducing the size we can
    13 	 * improve startup performance and reduce memory usage. ColorSync on
    14 	 * 10.5 uses 4097 which is perhaps because they use a fixed point
    15 	 * representation where 1. is represented by 0x1000. */
    16 #define PRECACHE_OUTPUT_SIZE 8192
    17 #define PRECACHE_OUTPUT_MAX (PRECACHE_OUTPUT_SIZE-1)
    18 	uint8_t data[PRECACHE_OUTPUT_SIZE];
    19 };
    21 #ifdef _MSC_VER
    22 #define ALIGN __declspec(align(16))
    23 #else
    24 #define ALIGN __attribute__(( aligned (16) ))
    25 #endif
    27 struct _qcms_transform {
    28 	float ALIGN matrix[3][4];
    29 	float *input_gamma_table_r;
    30 	float *input_gamma_table_g;
    31 	float *input_gamma_table_b;
    33 	float *input_clut_table_r;
    34 	float *input_clut_table_g;
    35 	float *input_clut_table_b;
    36 	uint16_t input_clut_table_length;
    37 	float *r_clut;
    38 	float *g_clut;
    39 	float *b_clut;
    40 	uint16_t grid_size;
    41 	float *output_clut_table_r;
    42 	float *output_clut_table_g;
    43 	float *output_clut_table_b;
    44 	uint16_t output_clut_table_length;
    46 	float *input_gamma_table_gray;
    48 	float out_gamma_r;
    49 	float out_gamma_g;
    50 	float out_gamma_b;
    52 	float out_gamma_gray;
    54 	uint16_t *output_gamma_lut_r;
    55 	uint16_t *output_gamma_lut_g;
    56 	uint16_t *output_gamma_lut_b;
    58 	uint16_t *output_gamma_lut_gray;
    60 	size_t output_gamma_lut_r_length;
    61 	size_t output_gamma_lut_g_length;
    62 	size_t output_gamma_lut_b_length;
    64 	size_t output_gamma_lut_gray_length;
    66 	struct precache_output *output_table_r;
    67 	struct precache_output *output_table_g;
    68 	struct precache_output *output_table_b;
    70 	void (*transform_fn)(struct _qcms_transform *transform, unsigned char *src, unsigned char *dest, size_t length);
    71 };
    73 struct matrix {
    74 	float m[3][3];
    75 	bool invalid;
    76 };
    78 struct qcms_modular_transform;
    80 typedef void (*transform_module_fn_t)(struct qcms_modular_transform *transform, float *src, float *dest, size_t length);
    82 struct qcms_modular_transform {
    83 	struct matrix matrix;
    84 	float tx, ty, tz;
    86 	float *input_clut_table_r;
    87 	float *input_clut_table_g;
    88 	float *input_clut_table_b;
    89 	uint16_t input_clut_table_length;
    90 	float *r_clut;
    91 	float *g_clut;
    92 	float *b_clut;
    93 	uint16_t grid_size;
    94 	float *output_clut_table_r;
    95 	float *output_clut_table_g;
    96 	float *output_clut_table_b;
    97 	uint16_t output_clut_table_length;
    99 	uint16_t *output_gamma_lut_r;
   100 	uint16_t *output_gamma_lut_g;
   101 	uint16_t *output_gamma_lut_b;
   103 	size_t output_gamma_lut_r_length;
   104 	size_t output_gamma_lut_g_length;
   105 	size_t output_gamma_lut_b_length;
   107 	transform_module_fn_t transform_module_fn;
   108 	struct qcms_modular_transform *next_transform;
   109 };
   111 typedef int32_t s15Fixed16Number;
   112 typedef uint16_t uInt16Number;
   113 typedef uint8_t uInt8Number;
   115 struct XYZNumber {
   116 	s15Fixed16Number X;
   117 	s15Fixed16Number Y;
   118 	s15Fixed16Number Z;
   119 };
   121 struct curveType {
   122 	uint32_t type;
   123 	uint32_t count;
   124 	float parameter[7];
   125 	uInt16Number data[];
   126 };
   128 struct lutmABType {
   129 	uint8_t num_in_channels;
   130 	uint8_t num_out_channels;
   131 	// 16 is the upperbound, actual is 0..num_in_channels.
   132 	uint8_t num_grid_points[16];
   134 	s15Fixed16Number e00;
   135 	s15Fixed16Number e01;
   136 	s15Fixed16Number e02;
   137 	s15Fixed16Number e03;
   138 	s15Fixed16Number e10;
   139 	s15Fixed16Number e11;
   140 	s15Fixed16Number e12;
   141 	s15Fixed16Number e13;
   142 	s15Fixed16Number e20;
   143 	s15Fixed16Number e21;
   144 	s15Fixed16Number e22;
   145 	s15Fixed16Number e23;
   147 	// reversed elements (for mBA)
   148 	bool reversed;
   150 	float *clut_table;
   151 	struct curveType *a_curves[10];
   152 	struct curveType *b_curves[10];
   153 	struct curveType *m_curves[10];
   154 	float clut_table_data[];
   155 };
   157 /* should lut8Type and lut16Type be different types? */
   158 struct lutType { // used by lut8Type/lut16Type (mft2) only
   159 	uint8_t num_input_channels;
   160 	uint8_t num_output_channels;
   161 	uint8_t num_clut_grid_points;
   163 	s15Fixed16Number e00;
   164 	s15Fixed16Number e01;
   165 	s15Fixed16Number e02;
   166 	s15Fixed16Number e10;
   167 	s15Fixed16Number e11;
   168 	s15Fixed16Number e12;
   169 	s15Fixed16Number e20;
   170 	s15Fixed16Number e21;
   171 	s15Fixed16Number e22;
   173 	uint16_t num_input_table_entries;
   174 	uint16_t num_output_table_entries;
   176 	float *input_table;
   177 	float *clut_table;
   178 	float *output_table;
   180 	float table_data[];
   181 };
   182 #if 0
   183 /* this is from an intial idea of having the struct correspond to the data in
   184  * the file. I decided that it wasn't a good idea.
   185  */
   186 struct tag_value {
   187 	uint32_t type;
   188 	union {
   189 		struct {
   190 			uint32_t reserved;
   191 			struct {
   192 				s15Fixed16Number X;
   193 				s15Fixed16Number Y;
   194 				s15Fixed16Number Z;
   195 			} XYZNumber;
   196 		} XYZType;
   197 	};
   198 }; // I guess we need to pack this?
   199 #endif
   201 #define RGB_SIGNATURE  0x52474220
   202 #define GRAY_SIGNATURE 0x47524159
   203 #define XYZ_SIGNATURE  0x58595A20
   204 #define LAB_SIGNATURE  0x4C616220
   206 struct _qcms_profile {
   207 	uint32_t class;
   208 	uint32_t color_space;
   209 	uint32_t pcs;
   210 	qcms_intent rendering_intent;
   211 	struct XYZNumber redColorant;
   212 	struct XYZNumber blueColorant;
   213 	struct XYZNumber greenColorant;
   214 	struct curveType *redTRC;
   215 	struct curveType *blueTRC;
   216 	struct curveType *greenTRC;
   217 	struct curveType *grayTRC;
   218 	struct lutType *A2B0;
   219 	struct lutType *B2A0;
   220 	struct lutmABType *mAB;
   221 	struct lutmABType *mBA;
   222 	struct matrix chromaticAdaption;
   224 	struct precache_output *output_table_r;
   225 	struct precache_output *output_table_g;
   226 	struct precache_output *output_table_b;
   227 };
   229 #ifdef _MSC_VER
   230 #define inline _inline
   231 #endif
   233 /* produces the nearest float to 'a' with a maximum error
   234  * of 1/1024 which happens for large values like 0x40000040 */
   235 static inline float s15Fixed16Number_to_float(s15Fixed16Number a)
   236 {
   237 	return ((int32_t)a)/65536.f;
   238 }
   240 static inline s15Fixed16Number double_to_s15Fixed16Number(double v)
   241 {
   242 	return (int32_t)(v*65536);
   243 }
   245 static inline float uInt8Number_to_float(uInt8Number a)
   246 {
   247 	return ((int32_t)a)/255.f;
   248 }
   250 static inline float uInt16Number_to_float(uInt16Number a)
   251 {
   252 	return ((int32_t)a)/65535.f;
   253 }
   256 void precache_release(struct precache_output *p);
   257 qcms_bool set_rgb_colorants(qcms_profile *profile, qcms_CIE_xyY white_point, qcms_CIE_xyYTRIPLE primaries);
   258 qcms_bool get_rgb_colorants(struct matrix *colorants, qcms_CIE_xyY white_point, qcms_CIE_xyYTRIPLE primaries);
   260 void qcms_transform_data_rgb_out_lut_sse2(qcms_transform *transform,
   261                                           unsigned char *src,
   262                                           unsigned char *dest,
   263                                           size_t length);
   264 void qcms_transform_data_rgba_out_lut_sse2(qcms_transform *transform,
   265                                           unsigned char *src,
   266                                           unsigned char *dest,
   267                                           size_t length);
   268 void qcms_transform_data_rgb_out_lut_sse1(qcms_transform *transform,
   269                                           unsigned char *src,
   270                                           unsigned char *dest,
   271                                           size_t length);
   272 void qcms_transform_data_rgba_out_lut_sse1(qcms_transform *transform,
   273                                           unsigned char *src,
   274                                           unsigned char *dest,
   275                                           size_t length);
   277 void qcms_transform_data_rgb_out_lut_altivec(qcms_transform *transform,
   278                                              unsigned char *src,
   279                                              unsigned char *dest,
   280                                              size_t length);
   281 void qcms_transform_data_rgba_out_lut_altivec(qcms_transform *transform,
   282                                               unsigned char *src,
   283                                               unsigned char *dest,
   284                                               size_t length);
   286 extern qcms_bool qcms_supports_iccv4;
   288 #ifdef _MSC_VER
   290 long __cdecl _InterlockedIncrement(long volatile *);
   291 long __cdecl _InterlockedDecrement(long volatile *);
   292 #pragma intrinsic(_InterlockedIncrement)
   293 #pragma intrinsic(_InterlockedDecrement)
   295 #define qcms_atomic_increment(x) _InterlockedIncrement((long volatile *)&x)
   296 #define qcms_atomic_decrement(x) _InterlockedDecrement((long volatile*)&x)
   298 #else
   300 #define qcms_atomic_increment(x) __sync_add_and_fetch(&x, 1)
   301 #define qcms_atomic_decrement(x) __sync_sub_and_fetch(&x, 1)
   303 #endif
   306 #ifdef NATIVE_OUTPUT
   307 # define RGB_OUTPUT_COMPONENTS 4
   308 # define RGBA_OUTPUT_COMPONENTS 4
   309 # ifdef IS_LITTLE_ENDIAN
   310 #  define OUTPUT_A_INDEX 3
   311 #  define OUTPUT_R_INDEX 2
   312 #  define OUTPUT_G_INDEX 1
   313 #  define OUTPUT_B_INDEX 0
   314 # else
   315 #  define OUTPUT_A_INDEX 0
   316 #  define OUTPUT_R_INDEX 1
   317 #  define OUTPUT_G_INDEX 2
   318 #  define OUTPUT_B_INDEX 3
   319 # endif
   320 #else
   321 # define RGB_OUTPUT_COMPONENTS 3
   322 # define RGBA_OUTPUT_COMPONENTS 4
   323 # define OUTPUT_R_INDEX 0
   324 # define OUTPUT_G_INDEX 1
   325 # define OUTPUT_B_INDEX 2
   326 # define OUTPUT_A_INDEX 3
   327 #endif

mercurial