qcmsint.h 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342
  1. /* vim: set ts=8 sw=8 noexpandtab: */
  2. // qcms
  3. // Copyright (C) 2009 Mozilla Foundation
  4. //
  5. // Permission is hereby granted, free of charge, to any person obtaining
  6. // a copy of this software and associated documentation files (the "Software"),
  7. // to deal in the Software without restriction, including without limitation
  8. // the rights to use, copy, modify, merge, publish, distribute, sublicense,
  9. // and/or sell copies of the Software, and to permit persons to whom the Software
  10. // is furnished to do so, subject to the following conditions:
  11. //
  12. // The above copyright notice and this permission notice shall be included in
  13. // all copies or substantial portions of the Software.
  14. //
  15. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  16. // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO
  17. // THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  18. // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  19. // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  20. // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  21. // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  22. #include "qcms.h"
  23. #include "qcmstypes.h"
  24. /* used as a lookup table for the output transformation.
  25. * we refcount them so we only need to have one around per output
  26. * profile, instead of duplicating them per transform */
  27. struct precache_output
  28. {
  29. int ref_count;
  30. /* We previously used a count of 65536 here but that seems like more
  31. * precision than we actually need. By reducing the size we can
  32. * improve startup performance and reduce memory usage. ColorSync on
  33. * 10.5 uses 4097 which is perhaps because they use a fixed point
  34. * representation where 1. is represented by 0x1000. */
  35. #define PRECACHE_OUTPUT_SIZE 8192
  36. #define PRECACHE_OUTPUT_MAX (PRECACHE_OUTPUT_SIZE-1)
  37. uint8_t data[PRECACHE_OUTPUT_SIZE];
  38. };
  39. #ifdef _MSC_VER
  40. #define ALIGN __declspec(align(16))
  41. #else
  42. #define ALIGN __attribute__(( aligned (16) ))
  43. #endif
  44. typedef struct _qcms_format_type {
  45. int r;
  46. int b;
  47. } qcms_format_type;
  48. struct _qcms_transform {
  49. float ALIGN matrix[3][4];
  50. float *input_gamma_table_r;
  51. float *input_gamma_table_g;
  52. float *input_gamma_table_b;
  53. float *input_clut_table_r;
  54. float *input_clut_table_g;
  55. float *input_clut_table_b;
  56. uint16_t input_clut_table_length;
  57. float *r_clut;
  58. float *g_clut;
  59. float *b_clut;
  60. uint16_t grid_size;
  61. float *output_clut_table_r;
  62. float *output_clut_table_g;
  63. float *output_clut_table_b;
  64. uint16_t output_clut_table_length;
  65. float *input_gamma_table_gray;
  66. float out_gamma_r;
  67. float out_gamma_g;
  68. float out_gamma_b;
  69. float out_gamma_gray;
  70. uint16_t *output_gamma_lut_r;
  71. uint16_t *output_gamma_lut_g;
  72. uint16_t *output_gamma_lut_b;
  73. uint16_t *output_gamma_lut_gray;
  74. size_t output_gamma_lut_r_length;
  75. size_t output_gamma_lut_g_length;
  76. size_t output_gamma_lut_b_length;
  77. size_t output_gamma_lut_gray_length;
  78. struct precache_output *output_table_r;
  79. struct precache_output *output_table_g;
  80. struct precache_output *output_table_b;
  81. void (*transform_fn)(struct _qcms_transform *transform, unsigned char *src, unsigned char *dest, size_t length, struct _qcms_format_type output_format);
  82. unsigned char floor_cache[256];
  83. unsigned char ceil_cache[256];
  84. float r_cache[256];
  85. #define TRANSFORM_FLAG_MATRIX 0x0001
  86. #define TRANSFORM_FLAG_CLUT_CACHE 0x0002
  87. uint16_t transform_flags;
  88. };
  89. struct matrix {
  90. float m[3][3];
  91. bool invalid;
  92. };
  93. struct qcms_modular_transform;
  94. typedef void (*transform_module_fn_t)(struct qcms_modular_transform *transform, float *src, float *dest, size_t length);
  95. struct qcms_modular_transform {
  96. struct matrix matrix;
  97. float tx, ty, tz;
  98. float *input_clut_table_r;
  99. float *input_clut_table_g;
  100. float *input_clut_table_b;
  101. uint16_t input_clut_table_length;
  102. float *r_clut;
  103. float *g_clut;
  104. float *b_clut;
  105. uint16_t grid_size;
  106. float *output_clut_table_r;
  107. float *output_clut_table_g;
  108. float *output_clut_table_b;
  109. uint16_t output_clut_table_length;
  110. uint16_t *output_gamma_lut_r;
  111. uint16_t *output_gamma_lut_g;
  112. uint16_t *output_gamma_lut_b;
  113. size_t output_gamma_lut_r_length;
  114. size_t output_gamma_lut_g_length;
  115. size_t output_gamma_lut_b_length;
  116. transform_module_fn_t transform_module_fn;
  117. struct qcms_modular_transform *next_transform;
  118. };
  119. typedef int32_t s15Fixed16Number;
  120. typedef uint16_t uInt16Number;
  121. typedef uint8_t uInt8Number;
  122. struct XYZNumber {
  123. s15Fixed16Number X;
  124. s15Fixed16Number Y;
  125. s15Fixed16Number Z;
  126. };
  127. struct curveType {
  128. uint32_t type;
  129. uint32_t count;
  130. float parameter[7];
  131. uInt16Number data[];
  132. };
  133. struct lutmABType {
  134. uint8_t num_in_channels;
  135. uint8_t num_out_channels;
  136. // 16 is the upperbound, actual is 0..num_in_channels.
  137. uint8_t num_grid_points[16];
  138. s15Fixed16Number e00;
  139. s15Fixed16Number e01;
  140. s15Fixed16Number e02;
  141. s15Fixed16Number e03;
  142. s15Fixed16Number e10;
  143. s15Fixed16Number e11;
  144. s15Fixed16Number e12;
  145. s15Fixed16Number e13;
  146. s15Fixed16Number e20;
  147. s15Fixed16Number e21;
  148. s15Fixed16Number e22;
  149. s15Fixed16Number e23;
  150. // reversed elements (for mBA)
  151. bool reversed;
  152. float *clut_table;
  153. struct curveType *a_curves[10];
  154. struct curveType *b_curves[10];
  155. struct curveType *m_curves[10];
  156. float clut_table_data[];
  157. };
  158. /* should lut8Type and lut16Type be different types? */
  159. struct lutType { // used by lut8Type/lut16Type (mft2) only
  160. uint8_t num_input_channels;
  161. uint8_t num_output_channels;
  162. 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;
  172. uint16_t num_input_table_entries;
  173. uint16_t num_output_table_entries;
  174. float *input_table;
  175. float *clut_table;
  176. float *output_table;
  177. float table_data[];
  178. };
  179. struct vcgtType {
  180. /* data contains three gamma channels: R[length], then G[length], then
  181. * B[length]. */
  182. uint16_t *data;
  183. size_t length;
  184. };
  185. #if 0
  186. /* this is from an intial idea of having the struct correspond to the data in
  187. * the file. I decided that it wasn't a good idea.
  188. */
  189. struct tag_value {
  190. uint32_t type;
  191. union {
  192. struct {
  193. uint32_t reserved;
  194. struct {
  195. s15Fixed16Number X;
  196. s15Fixed16Number Y;
  197. s15Fixed16Number Z;
  198. } XYZNumber;
  199. } XYZType;
  200. };
  201. }; // I guess we need to pack this?
  202. #endif
  203. #define RGB_SIGNATURE 0x52474220
  204. #define GRAY_SIGNATURE 0x47524159
  205. #define XYZ_SIGNATURE 0x58595A20
  206. #define LAB_SIGNATURE 0x4C616220
  207. struct _qcms_profile {
  208. uint32_t icc_version;
  209. char description[64];
  210. uint32_t class;
  211. uint32_t color_space;
  212. uint32_t pcs;
  213. qcms_intent rendering_intent;
  214. struct XYZNumber mediaWhitePoint;
  215. struct XYZNumber redColorant;
  216. struct XYZNumber blueColorant;
  217. struct XYZNumber greenColorant;
  218. struct curveType *redTRC;
  219. struct curveType *blueTRC;
  220. struct curveType *greenTRC;
  221. struct curveType *grayTRC;
  222. struct lutType *A2B0;
  223. struct lutType *B2A0;
  224. struct lutmABType *mAB;
  225. struct lutmABType *mBA;
  226. struct matrix chromaticAdaption;
  227. struct vcgtType vcgt;
  228. struct precache_output *output_table_r;
  229. struct precache_output *output_table_g;
  230. struct precache_output *output_table_b;
  231. };
  232. #ifdef _MSC_VER
  233. #define inline _inline
  234. #endif
  235. /* produces the nearest float to 'a' with a maximum error
  236. * of 1/1024 which happens for large values like 0x40000040 */
  237. static inline float s15Fixed16Number_to_float(s15Fixed16Number a)
  238. {
  239. return ((int32_t)a)/65536.f;
  240. }
  241. static inline s15Fixed16Number double_to_s15Fixed16Number(double v)
  242. {
  243. return (int32_t)(v*65536);
  244. }
  245. static inline float uInt8Number_to_float(uInt8Number a)
  246. {
  247. return ((int32_t)a)/255.f;
  248. }
  249. static inline float uInt16Number_to_float(uInt16Number a)
  250. {
  251. return ((int32_t)a)/65535.f;
  252. }
  253. void precache_release(struct precache_output *p);
  254. qcms_bool set_rgb_colorants(qcms_profile *profile, qcms_CIE_xyY white_point, qcms_CIE_xyYTRIPLE primaries);
  255. void qcms_transform_data_rgb_out_lut_sse2(qcms_transform *transform,
  256. unsigned char *src,
  257. unsigned char *dest,
  258. size_t length,
  259. qcms_format_type output_format);
  260. void qcms_transform_data_rgba_out_lut_sse2(qcms_transform *transform,
  261. unsigned char *src,
  262. unsigned char *dest,
  263. size_t length,
  264. qcms_format_type output_format);
  265. void qcms_transform_data_tetra_clut_rgba_sse2(qcms_transform* transform,
  266. unsigned char* src,
  267. unsigned char* dest,
  268. size_t length,
  269. qcms_format_type output_format);
  270. void qcms_transform_build_clut_cache(qcms_transform* transform);
  271. extern qcms_bool qcms_supports_iccv4;
  272. #ifdef _MSC_VER
  273. long __cdecl _InterlockedIncrement(long volatile *);
  274. long __cdecl _InterlockedDecrement(long volatile *);
  275. #pragma intrinsic(_InterlockedIncrement)
  276. #pragma intrinsic(_InterlockedDecrement)
  277. #define qcms_atomic_increment(x) _InterlockedIncrement((long volatile *)&x)
  278. #define qcms_atomic_decrement(x) _InterlockedDecrement((long volatile*)&x)
  279. #else
  280. #define qcms_atomic_increment(x) __sync_add_and_fetch(&x, 1)
  281. #define qcms_atomic_decrement(x) __sync_sub_and_fetch(&x, 1)
  282. #endif