gdevpsds.c 31 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204
  1. /* Copyright (C) 1997, 2000 Aladdin Enterprises. All rights reserved.
  2. This software is provided AS-IS with no warranty, either express or
  3. implied.
  4. This software is distributed under license and may not be copied,
  5. modified or distributed except as expressly authorized under the terms
  6. of the license contained in the file LICENSE in this distribution.
  7. For more information about licensing, please refer to
  8. http://www.ghostscript.com/licensing/. For information on
  9. commercial licensing, go to http://www.artifex.com/licensing/ or
  10. contact Artifex Software, Inc., 101 Lucas Valley Road #110,
  11. San Rafael, CA 94903, U.S.A., +1(415)492-9861.
  12. */
  13. /* $Id: gdevpsds.c,v 1.14 2005/02/26 18:07:43 igor Exp $ */
  14. /* Image processing streams for PostScript and PDF writers */
  15. #include "gx.h"
  16. #include "memory_.h"
  17. #include "gserrors.h"
  18. #include "gxdcconv.h"
  19. #include "gdevpsds.h"
  20. #include "gxbitmap.h"
  21. #include "gxcspace.h"
  22. #include "gsdcolor.h"
  23. #include "gscspace.h"
  24. #include "gxdevcli.h"
  25. /* ---------------- Convert between 1/2/4/12 and 8 bits ---------------- */
  26. gs_private_st_simple(st_1248_state, stream_1248_state, "stream_1248_state");
  27. /* Initialize an expansion or reduction stream. */
  28. int
  29. s_1248_init(stream_1248_state *ss, int Columns, int samples_per_pixel)
  30. {
  31. ss->samples_per_row = Columns * samples_per_pixel;
  32. return ss->template->init((stream_state *)ss);
  33. }
  34. /* Initialize the state. */
  35. private int
  36. s_1_init(stream_state * st)
  37. {
  38. stream_1248_state *const ss = (stream_1248_state *) st;
  39. ss->left = ss->samples_per_row;
  40. ss->bits_per_sample = 1;
  41. return 0;
  42. }
  43. private int
  44. s_2_init(stream_state * st)
  45. {
  46. stream_1248_state *const ss = (stream_1248_state *) st;
  47. ss->left = ss->samples_per_row;
  48. ss->bits_per_sample = 2;
  49. return 0;
  50. }
  51. private int
  52. s_4_init(stream_state * st)
  53. {
  54. stream_1248_state *const ss = (stream_1248_state *) st;
  55. ss->left = ss->samples_per_row;
  56. ss->bits_per_sample = 4;
  57. return 0;
  58. }
  59. private int
  60. s_12_init(stream_state * st)
  61. {
  62. stream_1248_state *const ss = (stream_1248_state *) st;
  63. ss->left = ss->samples_per_row;
  64. ss->bits_per_sample = 12; /* not needed */
  65. return 0;
  66. }
  67. /* Process one buffer. */
  68. #define BEGIN_1248\
  69. stream_1248_state * const ss = (stream_1248_state *)st;\
  70. const byte *p = pr->ptr;\
  71. const byte *rlimit = pr->limit;\
  72. byte *q = pw->ptr;\
  73. byte *wlimit = pw->limit;\
  74. uint left = ss->left;\
  75. int status;\
  76. int n
  77. #define END_1248\
  78. pr->ptr = p;\
  79. pw->ptr = q;\
  80. ss->left = left;\
  81. return status
  82. /* N-to-8 expansion */
  83. #define FOREACH_N_8(in, nout)\
  84. status = 0;\
  85. for ( ; p < rlimit; left -= n, q += n, ++p ) {\
  86. byte in = p[1];\
  87. n = min(left, nout);\
  88. if ( wlimit - q < n ) {\
  89. status = 1;\
  90. break;\
  91. }\
  92. switch ( n ) {\
  93. case 0: left = ss->samples_per_row; --p; continue;
  94. #define END_FOREACH_N_8\
  95. }\
  96. }
  97. private int
  98. s_N_8_process(stream_state * st, stream_cursor_read * pr,
  99. stream_cursor_write * pw, bool last)
  100. {
  101. BEGIN_1248;
  102. switch (ss->bits_per_sample) {
  103. case 1:{
  104. FOREACH_N_8(in, 8)
  105. case 8:
  106. q[8] = (byte) - (in & 1);
  107. case 7:
  108. q[7] = (byte) - ((in >> 1) & 1);
  109. case 6:
  110. q[6] = (byte) - ((in >> 2) & 1);
  111. case 5:
  112. q[5] = (byte) - ((in >> 3) & 1);
  113. case 4:
  114. q[4] = (byte) - ((in >> 4) & 1);
  115. case 3:
  116. q[3] = (byte) - ((in >> 5) & 1);
  117. case 2:
  118. q[2] = (byte) - ((in >> 6) & 1);
  119. case 1:
  120. q[1] = (byte) - (in >> 7);
  121. END_FOREACH_N_8;
  122. }
  123. break;
  124. case 2:{
  125. static const byte b2[4] =
  126. {0x00, 0x55, 0xaa, 0xff};
  127. FOREACH_N_8(in, 4)
  128. case 4:
  129. q[4] = b2[in & 3];
  130. case 3:
  131. q[3] = b2[(in >> 2) & 3];
  132. case 2:
  133. q[2] = b2[(in >> 4) & 3];
  134. case 1:
  135. q[1] = b2[in >> 6];
  136. END_FOREACH_N_8;
  137. }
  138. break;
  139. case 4:{
  140. static const byte b4[16] =
  141. {
  142. 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
  143. 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff
  144. };
  145. FOREACH_N_8(in, 2)
  146. case 2:
  147. q[2] = b4[in & 0xf];
  148. case 1:
  149. q[1] = b4[in >> 4];
  150. END_FOREACH_N_8;
  151. }
  152. break;
  153. default:
  154. return ERRC;
  155. }
  156. END_1248;
  157. }
  158. /* 12-to-8 "expansion" */
  159. private int
  160. s_12_8_process(stream_state * st, stream_cursor_read * pr,
  161. stream_cursor_write * pw, bool last)
  162. {
  163. BEGIN_1248;
  164. n = ss->samples_per_row; /* misuse n to avoid a compiler warning */
  165. status = 0;
  166. for (; rlimit - p >= 2; ++q) {
  167. if (q >= wlimit) {
  168. status = 1;
  169. break;
  170. }
  171. if (left == 0)
  172. left = n;
  173. if ((n - left) & 1) {
  174. q[1] = (byte)((p[1] << 4) | (p[2] >> 4));
  175. p += 2, --left;
  176. } else {
  177. q[1] = *++p;
  178. if (!--left)
  179. ++p;
  180. }
  181. }
  182. END_1248;
  183. }
  184. /* 8-to-N reduction */
  185. #define FOREACH_8_N(out, nin)\
  186. byte out;\
  187. status = 1;\
  188. for ( ; q < wlimit; left -= n, p += n, ++q ) {\
  189. n = min(left, nin);\
  190. if ( rlimit - p < n ) {\
  191. status = 0;\
  192. break;\
  193. }\
  194. out = 0;\
  195. switch ( n ) {\
  196. case 0: left = ss->samples_per_row; --q; continue;
  197. #define END_FOREACH_8_N\
  198. q[1] = out;\
  199. }\
  200. }
  201. private int
  202. s_8_N_process(stream_state * st, stream_cursor_read * pr,
  203. stream_cursor_write * pw, bool last)
  204. {
  205. BEGIN_1248;
  206. switch (ss->bits_per_sample) {
  207. case 1:{
  208. FOREACH_8_N(out, 8)
  209. case 8:
  210. out = p[8] >> 7;
  211. case 7:
  212. out |= (p[7] >> 7) << 1;
  213. case 6:
  214. out |= (p[6] >> 7) << 2;
  215. case 5:
  216. out |= (p[5] >> 7) << 3;
  217. case 4:
  218. out |= (p[4] >> 7) << 4;
  219. case 3:
  220. out |= (p[3] >> 7) << 5;
  221. case 2:
  222. out |= (p[2] >> 7) << 6;
  223. case 1:
  224. out |= p[1] & 0x80;
  225. END_FOREACH_8_N;
  226. }
  227. break;
  228. case 2:{
  229. FOREACH_8_N(out, 4)
  230. case 4:
  231. out |= p[4] >> 6;
  232. case 3:
  233. out |= (p[3] >> 6) << 2;
  234. case 2:
  235. out |= (p[2] >> 6) << 4;
  236. case 1:
  237. out |= p[1] & 0xc0;
  238. END_FOREACH_8_N;
  239. }
  240. break;
  241. case 4:{
  242. FOREACH_8_N(out, 2)
  243. case 2:
  244. out |= p[2] >> 4;
  245. case 1:
  246. out |= p[1] & 0xf0;
  247. END_FOREACH_8_N;
  248. }
  249. break;
  250. default:
  251. return ERRC;
  252. }
  253. END_1248;
  254. }
  255. const stream_template s_1_8_template = {
  256. &st_1248_state, s_1_init, s_N_8_process, 1, 8
  257. };
  258. const stream_template s_2_8_template = {
  259. &st_1248_state, s_2_init, s_N_8_process, 1, 4
  260. };
  261. const stream_template s_4_8_template = {
  262. &st_1248_state, s_4_init, s_N_8_process, 1, 2
  263. };
  264. const stream_template s_12_8_template = {
  265. &st_1248_state, s_12_init, s_12_8_process, 1, 2
  266. };
  267. const stream_template s_8_1_template = {
  268. &st_1248_state, s_1_init, s_8_N_process, 8, 1
  269. };
  270. const stream_template s_8_2_template = {
  271. &st_1248_state, s_2_init, s_8_N_process, 4, 1
  272. };
  273. const stream_template s_8_4_template = {
  274. &st_1248_state, s_4_init, s_8_N_process, 2, 1
  275. };
  276. /* ---------------- Color space conversion ---------------- */
  277. /* ------ Convert CMYK to RGB ------ */
  278. private_st_C2R_state();
  279. /* Initialize a CMYK => RGB conversion stream. */
  280. int
  281. s_C2R_init(stream_C2R_state *ss, const gs_imager_state *pis)
  282. {
  283. ss->pis = pis;
  284. return 0;
  285. }
  286. /* Set default parameter values (actually, just clear pointers). */
  287. private void
  288. s_C2R_set_defaults(stream_state * st)
  289. {
  290. stream_C2R_state *const ss = (stream_C2R_state *) st;
  291. ss->pis = 0;
  292. }
  293. /* Process one buffer. */
  294. private int
  295. s_C2R_process(stream_state * st, stream_cursor_read * pr,
  296. stream_cursor_write * pw, bool last)
  297. {
  298. stream_C2R_state *const ss = (stream_C2R_state *) st;
  299. const byte *p = pr->ptr;
  300. const byte *rlimit = pr->limit;
  301. byte *q = pw->ptr;
  302. byte *wlimit = pw->limit;
  303. for (; rlimit - p >= 4 && wlimit - q >= 3; p += 4, q += 3) {
  304. byte bc = p[1], bm = p[2], by = p[3], bk = p[4];
  305. frac rgb[3];
  306. color_cmyk_to_rgb(byte2frac(bc), byte2frac(bm), byte2frac(by),
  307. byte2frac(bk), ss->pis, rgb);
  308. q[1] = frac2byte(rgb[0]);
  309. q[2] = frac2byte(rgb[1]);
  310. q[3] = frac2byte(rgb[2]);
  311. }
  312. pr->ptr = p;
  313. pw->ptr = q;
  314. return (rlimit - p < 4 ? 0 : 1);
  315. }
  316. const stream_template s_C2R_template = {
  317. &st_C2R_state, 0 /*NULL */ , s_C2R_process, 4, 3, 0, s_C2R_set_defaults
  318. };
  319. /* ------ Convert any color space to Indexed ------ */
  320. private_st_IE_state();
  321. private
  322. ENUM_PTRS_WITH(ie_state_enum_ptrs, stream_IE_state *st) return 0;
  323. case 0: return ENUM_OBJ(st->Decode);
  324. case 1: return ENUM_BYTESTRING(&st->Table);
  325. ENUM_PTRS_END
  326. private
  327. RELOC_PTRS_WITH(ie_state_reloc_ptrs, stream_IE_state *st)
  328. {
  329. RELOC_VAR(st->Decode);
  330. RELOC_BYTESTRING_VAR(st->Table);
  331. }
  332. RELOC_PTRS_END
  333. /* Set defaults. */
  334. private void
  335. s_IE_set_defaults(stream_state * st)
  336. {
  337. stream_IE_state *const ss = (stream_IE_state *) st;
  338. ss->Decode = 0; /* clear pointers */
  339. gs_bytestring_from_string(&ss->Table, 0, 0);
  340. }
  341. /* Initialize the state. */
  342. private int
  343. s_IE_init(stream_state * st)
  344. {
  345. stream_IE_state *const ss = (stream_IE_state *) st;
  346. int key_index = (1 << ss->BitsPerIndex) * ss->NumComponents;
  347. int i;
  348. if (ss->Table.data == 0 || ss->Table.size < key_index)
  349. return ERRC; /****** WRONG ******/
  350. /* Initialize Table with default values. */
  351. memset(ss->Table.data, 0, ss->NumComponents);
  352. ss->Table.data[ss->Table.size - 1] = 0;
  353. for (i = 0; i < countof(ss->hash_table); ++i)
  354. ss->hash_table[i] = key_index;
  355. ss->next_index = 0;
  356. ss->in_bits_left = 0;
  357. ss->next_component = 0;
  358. ss->byte_out = 1;
  359. ss->x = 0;
  360. return 0;
  361. }
  362. /* Process a buffer. */
  363. private int
  364. s_IE_process(stream_state * st, stream_cursor_read * pr,
  365. stream_cursor_write * pw, bool last)
  366. {
  367. stream_IE_state *const ss = (stream_IE_state *) st;
  368. /* Constant values from the state */
  369. const int bpc = ss->BitsPerComponent;
  370. const int num_components = ss->NumComponents;
  371. const int end_index = (1 << ss->BitsPerIndex) * num_components;
  372. byte *const table = ss->Table.data;
  373. byte *const key = table + end_index;
  374. /* Dynamic values from the state */
  375. uint byte_in = ss->byte_in;
  376. int in_bits_left = ss->in_bits_left;
  377. int next_component = ss->next_component;
  378. uint byte_out = ss->byte_out;
  379. /* Other dynamic values */
  380. const byte *p = pr->ptr;
  381. const byte *rlimit = pr->limit;
  382. byte *q = pw->ptr;
  383. byte *wlimit = pw->limit;
  384. int status = 0;
  385. for (;;) {
  386. uint hash, reprobe;
  387. int i, index;
  388. /* Check for a filled output byte. */
  389. if (byte_out >= 0x100) {
  390. if (q >= wlimit) {
  391. status = 1;
  392. break;
  393. }
  394. *++q = (byte)byte_out;
  395. byte_out = 1;
  396. }
  397. /* Acquire a complete input value. */
  398. while (next_component < num_components) {
  399. const float *decode = &ss->Decode[next_component * 2];
  400. int sample;
  401. if (in_bits_left == 0) {
  402. if (p >= rlimit)
  403. goto out;
  404. byte_in = *++p;
  405. in_bits_left = 8;
  406. }
  407. /* An input sample can never span a byte boundary. */
  408. in_bits_left -= bpc;
  409. sample = (byte_in >> in_bits_left) & ((1 << bpc) - 1);
  410. /* Scale the sample according to Decode. */
  411. sample = (int)((decode[0] +
  412. (sample / (float)((1 << bpc) - 1) *
  413. (decode[1] - decode[0]))) * 255 + 0.5);
  414. key[next_component++] =
  415. (sample < 0 ? 0 : sample > 255 ? 255 : (byte)sample);
  416. }
  417. /* Look up the input value. */
  418. for (hash = 0, i = 0; i < num_components; ++i)
  419. hash = hash + 23 * key[i]; /* adhoc */
  420. reprobe = (hash / countof(ss->hash_table)) | 137; /* adhoc */
  421. for (hash %= countof(ss->hash_table);
  422. memcmp(table + ss->hash_table[hash], key, num_components);
  423. hash = (hash + reprobe) % countof(ss->hash_table)
  424. )
  425. DO_NOTHING;
  426. index = ss->hash_table[hash];
  427. if (index == end_index) {
  428. /* The match was on an empty entry. */
  429. if (ss->next_index == end_index) {
  430. /* Too many different values. */
  431. status = ERRC;
  432. break;
  433. }
  434. ss->hash_table[hash] = index = ss->next_index;
  435. ss->next_index += num_components;
  436. memcpy(table + index, key, num_components);
  437. }
  438. byte_out = (byte_out << ss->BitsPerIndex) + index / num_components;
  439. next_component = 0;
  440. if (++(ss->x) == ss->Width) {
  441. /* Handle input and output padding. */
  442. in_bits_left = 0;
  443. if (byte_out != 1)
  444. while (byte_out < 0x100)
  445. byte_out <<= 1;
  446. ss->x = 0;
  447. }
  448. }
  449. out:
  450. pr->ptr = p;
  451. pw->ptr = q;
  452. ss->byte_in = byte_in;
  453. ss->in_bits_left = in_bits_left;
  454. ss->next_component = next_component;
  455. ss->byte_out = byte_out;
  456. /* For simplicity, always update the record of the table size. */
  457. ss->Table.data[ss->Table.size - 1] =
  458. (ss->next_index == 0 ? 0 :
  459. ss->next_index / ss->NumComponents - 1);
  460. return status;
  461. }
  462. const stream_template s_IE_template = {
  463. &st_IE_state, s_IE_init, s_IE_process, 1, 1,
  464. 0 /* NULL */, s_IE_set_defaults
  465. };
  466. #if 0
  467. /* Test code */
  468. void
  469. test_IE(void)
  470. {
  471. const stream_template *const template = &s_IE_template;
  472. stream_IE_state state;
  473. stream_state *const ss = (stream_state *)&state;
  474. static const float decode[6] = {1, 0, 1, 0, 1, 0};
  475. static const byte in[] = {
  476. /*
  477. * Each row is 3 pixels x 3 components x 4 bits. Processing the
  478. * first two rows doesn't cause an error; processing all 3 rows
  479. * does.
  480. */
  481. 0x12, 0x35, 0x67, 0x9a, 0xb0,
  482. 0x56, 0x7d, 0xef, 0x12, 0x30,
  483. 0x88, 0x88, 0x88, 0x88, 0x80
  484. };
  485. byte table[3 * 5];
  486. int n;
  487. template->set_defaults(ss);
  488. state.BitsPerComponent = 4;
  489. state.NumComponents = 3;
  490. state.Width = 3;
  491. state.BitsPerIndex = 2;
  492. state.Decode = decode;
  493. gs_bytestring_from_bytes(&state.Table, table, 0, sizeof(table));
  494. for (n = 10; n <= 15; n += 5) {
  495. stream_cursor_read r;
  496. stream_cursor_write w;
  497. byte out[100];
  498. int status;
  499. s_IE_init(ss);
  500. r.ptr = in; --r.ptr;
  501. r.limit = r.ptr + n;
  502. w.ptr = out; --w.ptr;
  503. w.limit = w.ptr + sizeof(out);
  504. memset(table, 0xcc, sizeof(table));
  505. memset(out, 0xff, sizeof(out));
  506. dprintf1("processing %d bytes\n", n);
  507. status = template->process(ss, &r, &w, true);
  508. dprintf3("%d bytes read, %d bytes written, status = %d\n",
  509. (int)(r.ptr + 1 - in), (int)(w.ptr + 1 - out), status);
  510. debug_dump_bytes(table, table + sizeof(table), "table");
  511. debug_dump_bytes(out, w.ptr + 1, "out");
  512. }
  513. }
  514. #endif
  515. /* ---------------- Downsampling ---------------- */
  516. /* Return the number of samples after downsampling. */
  517. int
  518. s_Downsample_size_out(int size_in, int factor, bool pad)
  519. {
  520. return ((pad ? size_in + factor - 1 : size_in) / factor);
  521. }
  522. private void
  523. s_Downsample_set_defaults(register stream_state * st)
  524. {
  525. stream_Downsample_state *const ss = (stream_Downsample_state *)st;
  526. s_Downsample_set_defaults_inline(ss);
  527. }
  528. /* ------ Subsample ------ */
  529. gs_private_st_simple(st_Subsample_state, stream_Subsample_state,
  530. "stream_Subsample_state");
  531. /* Initialize the state. */
  532. private int
  533. s_Subsample_init(stream_state * st)
  534. {
  535. stream_Subsample_state *const ss = (stream_Subsample_state *) st;
  536. ss->x = ss->y = 0;
  537. return 0;
  538. }
  539. /* Process one buffer. */
  540. private int
  541. s_Subsample_process(stream_state * st, stream_cursor_read * pr,
  542. stream_cursor_write * pw, bool last)
  543. {
  544. stream_Subsample_state *const ss = (stream_Subsample_state *) st;
  545. const byte *p = pr->ptr;
  546. const byte *rlimit = pr->limit;
  547. byte *q = pw->ptr;
  548. byte *wlimit = pw->limit;
  549. int spp = ss->Colors;
  550. int width = ss->WidthIn, height = ss->HeightIn;
  551. int xf = ss->XFactor, yf = ss->YFactor;
  552. int xf2 = xf / 2, yf2 = yf / 2;
  553. int xlimit = (width / xf) * xf, ylimit = (height / yf) * yf;
  554. int xlast =
  555. (ss->padX && xlimit < width ? xlimit + (width % xf) / 2 : -1);
  556. int ylast =
  557. (ss->padY && ylimit < height ? ylimit + (height % yf) / 2 : -1);
  558. int x = ss->x, y = ss->y;
  559. int status = 0;
  560. if_debug4('w', "[w]subsample: x=%d, y=%d, rcount=%ld, wcount=%ld\n",
  561. x, y, (long)(rlimit - p), (long)(wlimit - q));
  562. for (; rlimit - p >= spp; p += spp) {
  563. if (((y % yf == yf2 && y < ylimit) || y == ylast) &&
  564. ((x % xf == xf2 && x < xlimit) || x == xlast)
  565. ) {
  566. if (wlimit - q < spp) {
  567. status = 1;
  568. break;
  569. }
  570. memcpy(q + 1, p + 1, spp);
  571. q += spp;
  572. }
  573. if (++x == width)
  574. x = 0, ++y;
  575. }
  576. if_debug5('w',
  577. "[w]subsample: x'=%d, y'=%d, read %ld, wrote %ld, status = %d\n",
  578. x, y, (long)(p - pr->ptr), (long)(q - pw->ptr), status);
  579. pr->ptr = p;
  580. pw->ptr = q;
  581. ss->x = x, ss->y = y;
  582. return status;
  583. }
  584. const stream_template s_Subsample_template = {
  585. &st_Subsample_state, s_Subsample_init, s_Subsample_process, 4, 4,
  586. 0 /* NULL */, s_Downsample_set_defaults
  587. };
  588. /* ------ Average ------ */
  589. private_st_Average_state();
  590. /* Set default parameter values (actually, just clear pointers). */
  591. private void
  592. s_Average_set_defaults(stream_state * st)
  593. {
  594. stream_Average_state *const ss = (stream_Average_state *) st;
  595. s_Downsample_set_defaults(st);
  596. /* Clear pointers */
  597. ss->sums = 0;
  598. }
  599. /* Initialize the state. */
  600. private int
  601. s_Average_init(stream_state * st)
  602. {
  603. stream_Average_state *const ss = (stream_Average_state *) st;
  604. ss->sum_size =
  605. ss->Colors * ((ss->WidthIn + ss->XFactor - 1) / ss->XFactor);
  606. ss->copy_size = ss->sum_size -
  607. (ss->padX || (ss->WidthIn % ss->XFactor == 0) ? 0 : ss->Colors);
  608. ss->sums =
  609. (uint *)gs_alloc_byte_array(st->memory, ss->sum_size,
  610. sizeof(uint), "Average sums");
  611. if (ss->sums == 0)
  612. return ERRC; /****** WRONG ******/
  613. memset(ss->sums, 0, ss->sum_size * sizeof(uint));
  614. return s_Subsample_init(st);
  615. }
  616. /* Release the state. */
  617. private void
  618. s_Average_release(stream_state * st)
  619. {
  620. stream_Average_state *const ss = (stream_Average_state *) st;
  621. gs_free_object(st->memory, ss->sums, "Average sums");
  622. }
  623. /* Process one buffer. */
  624. private int
  625. s_Average_process(stream_state * st, stream_cursor_read * pr,
  626. stream_cursor_write * pw, bool last)
  627. {
  628. stream_Average_state *const ss = (stream_Average_state *) st;
  629. const byte *p = pr->ptr;
  630. const byte *rlimit = pr->limit;
  631. byte *q = pw->ptr;
  632. byte *wlimit = pw->limit;
  633. int spp = ss->Colors;
  634. int width = ss->WidthIn;
  635. int xf = ss->XFactor, yf = ss->YFactor;
  636. int x = ss->x, y = ss->y;
  637. uint *sums = ss->sums;
  638. int status = 0;
  639. top:
  640. if (y == yf || (last && p >= rlimit && ss->padY && y != 0)) {
  641. /* We're copying averaged values to the output. */
  642. int ncopy = min(ss->copy_size - x, wlimit - q);
  643. if (ncopy) {
  644. int scale = xf * y;
  645. while (--ncopy >= 0)
  646. *++q = (byte) (sums[x++] / scale);
  647. }
  648. if (x < ss->copy_size) {
  649. status = 1;
  650. goto out;
  651. }
  652. /* Done copying. */
  653. x = y = 0;
  654. memset(sums, 0, ss->sum_size * sizeof(uint));
  655. }
  656. while (rlimit - p >= spp) {
  657. uint *bp = sums + x / xf * spp;
  658. int i;
  659. for (i = spp; --i >= 0;)
  660. *bp++ += *++p;
  661. if (++x == width) {
  662. x = 0;
  663. ++y;
  664. goto top;
  665. }
  666. }
  667. out:
  668. pr->ptr = p;
  669. pw->ptr = q;
  670. ss->x = x, ss->y = y;
  671. return status;
  672. }
  673. const stream_template s_Average_template = {
  674. &st_Average_state, s_Average_init, s_Average_process, 4, 4,
  675. s_Average_release, s_Average_set_defaults
  676. };
  677. /* ---------------- Image compression chooser ---------------- */
  678. private_st_compr_chooser_state();
  679. /* Initialize the state. */
  680. private int
  681. s_compr_chooser_init(stream_state * st)
  682. {
  683. stream_compr_chooser_state *const ss = (stream_compr_chooser_state *) st;
  684. ss->choice = 0;
  685. ss->width = ss->height = ss->depth = ss->bits_per_sample = 0;
  686. ss->sample = 0;
  687. ss->samples_count = 0;
  688. ss->bits_left = 0;
  689. ss->packed_data = 0;
  690. ss->lower_plateaus = ss->upper_plateaus = 0;
  691. ss->gradients = 0;
  692. return 0;
  693. }
  694. /* Set image dimensions. */
  695. int
  696. s_compr_chooser_set_dimensions(stream_compr_chooser_state * ss, int width,
  697. int height, int depth, int bits_per_sample)
  698. {
  699. ss->width = width;
  700. ss->height = height;
  701. ss->depth = depth;
  702. ss->bits_per_sample = bits_per_sample;
  703. ss->sample = gs_alloc_bytes(ss->memory, width * depth, "s_compr_chooser_set_dimensions");
  704. if (ss->sample == 0)
  705. return_error(gs_error_VMerror);
  706. return 0;
  707. }
  708. /* Release state. */
  709. private void
  710. s_compr_chooser_release(stream_state * st)
  711. {
  712. stream_compr_chooser_state *const ss = (stream_compr_chooser_state *) st;
  713. gs_free_object(ss->memory, ss->sample, "s_compr_chooser_release");
  714. }
  715. /* Estimate a row for photo/lineart recognition. */
  716. private void
  717. s_compr_chooser__estimate_row(stream_compr_chooser_state *const ss, byte *p)
  718. {
  719. /* This function uses a statistical algorithm being not well defined.
  720. We compute areas covered by gradients,
  721. separately with small width (line art)
  722. and with big width (photo).
  723. Making the choice based on the areas.
  724. Note that we deal with horizontal frequencies only.
  725. Dealing with vertical ones would be too expensive.
  726. */
  727. const int delta = 256 / 16; /* about 1/16 of the color range */
  728. const int max_lineart_boundary_width = 3; /* pixels */
  729. const int max_gradient_constant = 10; /* pixels */
  730. int i, j0 = 0, j1 = 0;
  731. int w0 = p[0], w1 = p[0], v;
  732. ulong plateau_count = 0, lower_plateaus = 0;
  733. ulong upper_plateaus = 0, gradients = 0;
  734. bool lower = false, upper = false;
  735. for (i = 1; i < ss->width; i++) {
  736. v = p[i];
  737. if (!lower) {
  738. if (w1 < v) {
  739. if (!upper)
  740. j1 = i - 1;
  741. w1 = v;
  742. upper = true;
  743. } else if (w1 == v && j1 < i - max_gradient_constant)
  744. j1 = i - max_gradient_constant; /* inner constant plateaw */
  745. else if (upper && w1 - delta > v) {
  746. /* end of upper plateau at w1-delta...w1 */
  747. for (j0 = i - 1; j0 > j1 && w1 - delta <= p[j0]; j0--) DO_NOTHING;
  748. /* upper plateau j0+1...i-1 */
  749. if(j0 > 0 && i < ss->width - 1) /* ignore sides */
  750. upper_plateaus += i - j0;
  751. plateau_count ++;
  752. if (j0 > j1) {
  753. /* upgrade j1...j0 */
  754. if (j0 > j1 + max_lineart_boundary_width)
  755. gradients += j0 - j1;
  756. }
  757. j1 = i;
  758. upper = false;
  759. w0 = w1;
  760. continue;
  761. }
  762. }
  763. if (!upper) {
  764. if (w0 > v) {
  765. if (!lower)
  766. j1 = i - 1;
  767. w0 = v;
  768. lower = true;
  769. } else if (w0 == v && j1 < i - max_gradient_constant)
  770. j1 = i - max_gradient_constant; /* inner constant plateaw */
  771. else if (lower && w0 + delta < v) {
  772. /* end of lower plateau at w0...w0+delta */
  773. for (j0 = i - 1; j0 > j1 && w0 + delta >= p[j0]; j0--) DO_NOTHING;
  774. /* lower plateau j0+1...i-1 */
  775. if(j0 > 0 && i < ss->width - 1) /* ignore sides */
  776. lower_plateaus += i - j0;
  777. plateau_count ++;
  778. if (j0 > j1) {
  779. /* downgrade j1...j0 */
  780. if (j0 > j1 + max_lineart_boundary_width)
  781. gradients += j0 - j1;
  782. }
  783. j1 = i;
  784. lower = false;
  785. w1 = w0;
  786. }
  787. }
  788. }
  789. if (plateau_count > ss->width / 6) {
  790. /* Possibly a dithering, can't recognize.
  791. It would be better to estimate frequency histogram rather than
  792. rough quantity, but we hope that the simpler test can work fine.
  793. */
  794. } else if (!plateau_count) /* a pseudo-constant color through entire row */
  795. DO_NOTHING; /* ignore such lines */
  796. else {
  797. int plateaus;
  798. ss->lower_plateaus += lower_plateaus;
  799. ss->upper_plateaus += upper_plateaus;
  800. ss->gradients += gradients;
  801. plateaus = min(ss->lower_plateaus, ss->upper_plateaus); /* (fore/back)ground */
  802. if (ss->gradients >= 10000 && ss->gradients > plateaus / 6)
  803. ss->choice = 1; /* choice is made : photo */
  804. else if (plateaus >= 100000 && plateaus / 5000 >= ss->gradients)
  805. ss->choice = 2; /* choice is made : lineart */
  806. }
  807. }
  808. /* Recognize photo/lineart. */
  809. private void
  810. s_compr_chooser__recognize(stream_compr_chooser_state * ss)
  811. {
  812. int i;
  813. byte *p = ss->sample;
  814. for (i = 0; i < ss->depth; i++, p += ss->width)
  815. s_compr_chooser__estimate_row(ss, p);
  816. /* todo: make decision */
  817. }
  818. /* Uppack data and recognize photo/lineart. */
  819. private void
  820. s_compr_chooser__unpack_and_recognize(stream_compr_chooser_state *const ss,
  821. const byte *data, int length)
  822. {
  823. /*
  824. * Input samples are packed ABCABCABC..., but the sample[] array of
  825. * unpacked values is stored AAA...BBB...CCC. i counts samples within
  826. * a pixel, multiplied by width; j counts pixels.
  827. */
  828. uint i = (ss->samples_count % ss->depth) * ss->width;
  829. uint j = ss->samples_count / ss->depth;
  830. const byte *p = data;
  831. int l = length;
  832. while (l) {
  833. if (ss->bits_left < 8) {
  834. uint k = (sizeof(ss->packed_data) * 8 - ss->bits_left) / 8;
  835. k = min(k, l);
  836. for (; k; k--, l--, p++, ss->bits_left += 8)
  837. ss->packed_data = (ss->packed_data << 8) + *p;
  838. }
  839. while (ss->bits_left >= ss->bits_per_sample) {
  840. uint k = ss->bits_left - ss->bits_per_sample;
  841. ulong v = ss->packed_data >> k;
  842. ss->packed_data -= (v << k);
  843. ss->bits_left -= ss->bits_per_sample;
  844. if (ss->bits_per_sample > 8)
  845. v >>= ss->bits_per_sample - 8;
  846. else
  847. v <<= 8 - ss->bits_per_sample;
  848. ss->sample[i + j] = (byte)v; /* scaled to 0...255 */
  849. i += ss->width;
  850. if (i >= ss->width * ss->depth)
  851. i = 0, j++;
  852. ss->samples_count++;
  853. if (ss->samples_count >= ss->width * ss->depth) {
  854. s_compr_chooser__recognize(ss);
  855. ss->packed_data = 0;
  856. ss->bits_left = 0;
  857. ss->samples_count = 0;
  858. i = j = 0;
  859. }
  860. }
  861. }
  862. }
  863. /* Process a buffer. */
  864. private int
  865. s_compr_chooser_process(stream_state * st, stream_cursor_read * pr,
  866. stream_cursor_write * pw, bool last)
  867. {
  868. stream_compr_chooser_state *const ss = (stream_compr_chooser_state *) st;
  869. int l = pr->limit - pr->ptr;
  870. if (ss->width >= 3) /* Can't process narrow images. */
  871. s_compr_chooser__unpack_and_recognize(ss, pr->ptr + 1, l);
  872. pr->ptr += l;
  873. return 0;
  874. }
  875. const stream_template s_compr_chooser_template = {
  876. &st_compr_chooser_state, s_compr_chooser_init, s_compr_chooser_process, 1, 1,
  877. s_compr_chooser_release, 0 /* NULL */
  878. };
  879. /* Get choice */
  880. uint
  881. s_compr_chooser__get_choice(stream_compr_chooser_state *ss, bool force)
  882. {
  883. ulong plateaus = min(ss->lower_plateaus, ss->upper_plateaus);
  884. if (ss->choice)
  885. return ss->choice;
  886. if (force) {
  887. if (ss->gradients > plateaus / 12) /* messenger16.pdf, page 3. */
  888. return 1; /* photo */
  889. else if (plateaus / 5000 >= ss->gradients)
  890. return 2; /* lineart */
  891. }
  892. return 0;
  893. }
  894. /* ---------------- Am image color conversion filter ---------------- */
  895. private_st_image_colors_state();
  896. /* Initialize the state. */
  897. private int
  898. s_image_colors_init(stream_state * st)
  899. {
  900. stream_image_colors_state *const ss = (stream_image_colors_state *) st;
  901. ss->width = ss->height = ss->depth = ss->bits_per_sample = 0;
  902. ss->output_bits_buffer = 0;
  903. ss->output_bits_buffered = 0;
  904. ss->output_depth = 1;
  905. ss->output_component_index = ss->output_depth;
  906. ss->output_bits_per_sample = 1;
  907. ss->output_component_bits_written = 0;
  908. ss->raster = 0;
  909. ss->row_bits = 0;
  910. ss->row_bits_passed = 0;
  911. ss->row_alignment_bytes = 0;
  912. ss->row_alignment_bytes_left = 0;
  913. ss->input_component_index = 0;
  914. ss->input_bits_buffer = 0;
  915. ss->input_bits_buffered = 0;
  916. ss->convert_color = 0;
  917. ss->pcs = 0;
  918. ss->pdev = 0;
  919. ss->pis = 0;
  920. return 0;
  921. }
  922. private int
  923. s_image_colors_convert_color_to_mask(stream_image_colors_state *ss)
  924. {
  925. int i, ii;
  926. for (i = ii = 0; i < ss->depth; i++, ii += 2)
  927. if (ss->input_color[i] < ss->MaskColor[ii] ||
  928. ss->input_color[i] > ss->MaskColor[ii + 1])
  929. break;
  930. ss->output_color[0] = (i < ss->depth ? 1 : 0);
  931. return 0;
  932. }
  933. private int
  934. s_image_colors_convert_to_device_color(stream_image_colors_state * ss)
  935. {
  936. gs_client_color cc;
  937. gx_device_color dc;
  938. int i, code;
  939. double v0 = (1 << ss->bits_per_sample) - 1;
  940. double v1 = (1 << ss->output_bits_per_sample) - 1;
  941. for (i = 0; i < ss->depth; i++)
  942. cc.paint.values[i] = ss->input_color[i] *
  943. (ss->Decode[i * 2 + 1] - ss->Decode[i * 2]) / v0 + ss->Decode[i * 2];
  944. code = ss->pcs->type->remap_color(&cc, ss->pcs, &dc, ss->pis,
  945. ss->pdev, gs_color_select_texture);
  946. if (code < 0)
  947. return code;
  948. for (i = 0; i < ss->output_depth; i++) {
  949. uint m = (1 << ss->pdev->color_info.comp_bits[i]) - 1;
  950. uint w = (dc.colors.pure >> ss->pdev->color_info.comp_shift[i]) & m;
  951. ss->output_color[i] = (uint)(v1 * w / m + 0.5);
  952. }
  953. return 0;
  954. }
  955. /* Set masc colors dimensions. */
  956. void
  957. s_image_colors_set_mask_colors(stream_image_colors_state * ss, uint *MaskColor)
  958. {
  959. ss->convert_color = s_image_colors_convert_color_to_mask;
  960. memcpy(ss->MaskColor, MaskColor, ss->depth * sizeof(MaskColor[0]) * 2);
  961. }
  962. /* Set image dimensions. */
  963. void
  964. s_image_colors_set_dimensions(stream_image_colors_state * ss,
  965. int width, int height, int depth, int bits_per_sample)
  966. {
  967. ss->width = width;
  968. ss->height = height;
  969. ss->depth = depth;
  970. ss->bits_per_sample = bits_per_sample;
  971. ss->row_bits = bits_per_sample * depth * width;
  972. ss->raster = bitmap_raster(ss->row_bits);
  973. ss->row_alignment_bytes = 0; /* (ss->raster * 8 - ss->row_bits) / 8) doesn't work. */
  974. }
  975. void
  976. s_image_colors_set_color_space(stream_image_colors_state * ss, gx_device *pdev,
  977. const gs_color_space *pcs, const gs_imager_state *pis,
  978. float *Decode)
  979. {
  980. ss->output_depth = pdev->color_info.num_components;
  981. ss->output_component_index = ss->output_depth;
  982. ss->output_bits_per_sample = pdev->color_info.comp_bits[0]; /* Same precision for all components. */
  983. ss->convert_color = s_image_colors_convert_to_device_color;
  984. ss->pdev = pdev;
  985. ss->pcs = pcs;
  986. ss->pis = pis;
  987. memcpy(ss->Decode, Decode, ss->depth * sizeof(Decode[0]) * 2);
  988. }
  989. /* Process a buffer. */
  990. private int
  991. s_image_colors_process(stream_state * st, stream_cursor_read * pr,
  992. stream_cursor_write * pw, bool last)
  993. {
  994. stream_image_colors_state *const ss = (stream_image_colors_state *) st;
  995. for (;;) {
  996. if (pw->ptr >= pw->limit)
  997. return 1;
  998. if (ss->row_bits_passed >= ss->row_bits) {
  999. ss->row_alignment_bytes_left = ss->row_alignment_bytes;
  1000. ss->input_bits_buffered = 0;
  1001. ss->input_bits_buffer = 0; /* Just to simplify the debugging. */
  1002. if (ss->output_bits_buffered) {
  1003. *(++pw->ptr) = ss->output_bits_buffer;
  1004. ss->output_bits_buffered = 0;
  1005. ss->output_bits_buffer = 0;
  1006. }
  1007. ss->row_bits_passed = 0;
  1008. continue;
  1009. }
  1010. if (ss->row_alignment_bytes_left) {
  1011. uint k = pr->limit - pr->ptr;
  1012. if (k > ss->row_alignment_bytes_left)
  1013. k = ss->row_alignment_bytes_left;
  1014. pr->ptr += k;
  1015. ss->row_alignment_bytes_left -= k;
  1016. if (pr->ptr >= pr->limit)
  1017. return 0;
  1018. }
  1019. if (ss->output_component_index < ss->output_depth) {
  1020. for (;ss->output_component_index < ss->output_depth;) {
  1021. uint fitting = (uint)(8 - ss->output_bits_buffered);
  1022. uint v, w, u, n, m;
  1023. if (pw->ptr >= pw->limit)
  1024. return 1;
  1025. v = ss->output_color[ss->output_component_index];
  1026. n = ss->output_bits_per_sample - ss->output_component_bits_written; /* no. of bits left */
  1027. w = v - ((v >> n) << n); /* the current component without written bits. */
  1028. if (fitting > n)
  1029. fitting = n; /* no. of bits to write. */
  1030. m = n - fitting; /* no. of bits will left. */
  1031. u = w >> m; /* bits to write (near lsb). */
  1032. ss->output_bits_buffer |= u << (8 - ss->output_bits_buffered - fitting);
  1033. ss->output_bits_buffered += fitting;
  1034. if (ss->output_bits_buffered >= 8) {
  1035. *(++pw->ptr) = ss->output_bits_buffer;
  1036. ss->output_bits_buffered = 0;
  1037. ss->output_bits_buffer = 0;
  1038. }
  1039. ss->output_component_bits_written += fitting;
  1040. if (ss->output_component_bits_written >= ss->output_bits_per_sample) {
  1041. ss->output_component_index++;
  1042. ss->output_component_bits_written = 0;
  1043. }
  1044. }
  1045. ss->row_bits_passed += ss->bits_per_sample * ss->depth;
  1046. continue;
  1047. }
  1048. if (ss->input_bits_buffered < ss->bits_per_sample) {
  1049. if (pr->ptr >= pr->limit)
  1050. return 0;
  1051. ss->input_bits_buffer = (ss->input_bits_buffer << 8) | *++pr->ptr;
  1052. ss->input_bits_buffered += 8;
  1053. /* fixme: delay shifting the input ptr until input_bits_buffer is cleaned. */
  1054. }
  1055. if (ss->input_bits_buffered >= ss->bits_per_sample) {
  1056. uint w;
  1057. ss->input_bits_buffered -= ss->bits_per_sample;
  1058. ss->input_color[ss->input_component_index] = w = ss->input_bits_buffer >> ss->input_bits_buffered;
  1059. ss->input_bits_buffer &= ~(w << ss->input_bits_buffered);
  1060. ss->input_component_index++;
  1061. if (ss->input_component_index >= ss->depth) {
  1062. int code = ss->convert_color(ss);
  1063. if (code < 0)
  1064. return ERRC;
  1065. ss->output_component_index = 0;
  1066. ss->input_component_index = 0;
  1067. }
  1068. }
  1069. }
  1070. }
  1071. const stream_template s__image_colors_template = {
  1072. &st_stream_image_colors_state, s_image_colors_init, s_image_colors_process, 1, 1,
  1073. NULL, NULL
  1074. };