jpc_t1enc.c 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959
  1. /*
  2. * Copyright (c) 1999-2000 Image Power, Inc. and the University of
  3. * British Columbia.
  4. * Copyright (c) 2001-2002 Michael David Adams.
  5. * All rights reserved.
  6. */
  7. /* __START_OF_JASPER_LICENSE__
  8. *
  9. * JasPer License Version 2.0
  10. *
  11. * Copyright (c) 2001-2006 Michael David Adams
  12. * Copyright (c) 1999-2000 Image Power, Inc.
  13. * Copyright (c) 1999-2000 The University of British Columbia
  14. *
  15. * All rights reserved.
  16. *
  17. * Permission is hereby granted, free of charge, to any person (the
  18. * "User") obtaining a copy of this software and associated documentation
  19. * files (the "Software"), to deal in the Software without restriction,
  20. * including without limitation the rights to use, copy, modify, merge,
  21. * publish, distribute, and/or sell copies of the Software, and to permit
  22. * persons to whom the Software is furnished to do so, subject to the
  23. * following conditions:
  24. *
  25. * 1. The above copyright notices and this permission notice (which
  26. * includes the disclaimer below) shall be included in all copies or
  27. * substantial portions of the Software.
  28. *
  29. * 2. The name of a copyright holder shall not be used to endorse or
  30. * promote products derived from the Software without specific prior
  31. * written permission.
  32. *
  33. * THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS
  34. * LICENSE. NO USE OF THE SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER
  35. * THIS DISCLAIMER. THE SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS
  36. * "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
  37. * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
  38. * PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO
  39. * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL
  40. * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING
  41. * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
  42. * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
  43. * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. NO ASSURANCES ARE
  44. * PROVIDED BY THE COPYRIGHT HOLDERS THAT THE SOFTWARE DOES NOT INFRINGE
  45. * THE PATENT OR OTHER INTELLECTUAL PROPERTY RIGHTS OF ANY OTHER ENTITY.
  46. * EACH COPYRIGHT HOLDER DISCLAIMS ANY LIABILITY TO THE USER FOR CLAIMS
  47. * BROUGHT BY ANY OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL
  48. * PROPERTY RIGHTS OR OTHERWISE. AS A CONDITION TO EXERCISING THE RIGHTS
  49. * GRANTED HEREUNDER, EACH USER HEREBY ASSUMES SOLE RESPONSIBILITY TO SECURE
  50. * ANY OTHER INTELLECTUAL PROPERTY RIGHTS NEEDED, IF ANY. THE SOFTWARE
  51. * IS NOT FAULT-TOLERANT AND IS NOT INTENDED FOR USE IN MISSION-CRITICAL
  52. * SYSTEMS, SUCH AS THOSE USED IN THE OPERATION OF NUCLEAR FACILITIES,
  53. * AIRCRAFT NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL
  54. * SYSTEMS, DIRECT LIFE SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH
  55. * THE FAILURE OF THE SOFTWARE OR SYSTEM COULD LEAD DIRECTLY TO DEATH,
  56. * PERSONAL INJURY, OR SEVERE PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH
  57. * RISK ACTIVITIES"). THE COPYRIGHT HOLDERS SPECIFICALLY DISCLAIM ANY
  58. * EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR HIGH RISK ACTIVITIES.
  59. *
  60. * __END_OF_JASPER_LICENSE__
  61. */
  62. /*
  63. * Tier 1 Encoder
  64. *
  65. * $Id: jpc_t1enc.c,v 1.2 2008-05-26 09:40:52 vp153 Exp $
  66. */
  67. /******************************************************************************\
  68. * Includes.
  69. \******************************************************************************/
  70. #include <stdio.h>
  71. #include <stdlib.h>
  72. #include <assert.h>
  73. #include "jasper/jas_fix.h"
  74. #include "jasper/jas_malloc.h"
  75. #include "jasper/jas_math.h"
  76. #include "jpc_t1enc.h"
  77. #include "jpc_t1cod.h"
  78. #include "jpc_enc.h"
  79. #include "jpc_cod.h"
  80. #include "jpc_math.h"
  81. static int jpc_encsigpass(jpc_mqenc_t *mqenc, int bitpos, int orient, int,
  82. jas_matrix_t *flags, jas_matrix_t *data, int term, long *nmsedec);
  83. static int jpc_encrefpass(jpc_mqenc_t *mqenc, int bitpos, int, jas_matrix_t *flags,
  84. jas_matrix_t *data, int term, long *nmsedec);
  85. static int jpc_encclnpass(jpc_mqenc_t *mqenc, int bitpos, int orient, int,
  86. int, jas_matrix_t *flags, jas_matrix_t *data, int term, long *nmsedec);
  87. static int jpc_encrawsigpass(jpc_bitstream_t *out, int bitpos, int,
  88. jas_matrix_t *flags, jas_matrix_t *data, int term, long *nmsedec);
  89. static int jpc_encrawrefpass(jpc_bitstream_t *out, int bitpos, int,
  90. jas_matrix_t *flags, jas_matrix_t *data, int term, long *nmsedec);
  91. /******************************************************************************\
  92. * Code for encoding code blocks.
  93. \******************************************************************************/
  94. /* Encode all of the code blocks associated with the current tile. */
  95. int jpc_enc_enccblks(jpc_enc_t *enc)
  96. {
  97. jpc_enc_tcmpt_t *tcmpt;
  98. jpc_enc_tcmpt_t *endcomps;
  99. jpc_enc_rlvl_t *lvl;
  100. jpc_enc_rlvl_t *endlvls;
  101. jpc_enc_band_t *band;
  102. jpc_enc_band_t *endbands;
  103. jpc_enc_cblk_t *cblk;
  104. jpc_enc_cblk_t *endcblks;
  105. int i;
  106. int j;
  107. int mx;
  108. int bmx;
  109. int v;
  110. jpc_enc_tile_t *tile;
  111. uint_fast32_t prcno;
  112. jpc_enc_prc_t *prc;
  113. tile = enc->curtile;
  114. endcomps = &tile->tcmpts[tile->numtcmpts];
  115. for (tcmpt = tile->tcmpts; tcmpt != endcomps; ++tcmpt) {
  116. endlvls = &tcmpt->rlvls[tcmpt->numrlvls];
  117. for (lvl = tcmpt->rlvls; lvl != endlvls; ++lvl) {
  118. if (!lvl->bands) {
  119. continue;
  120. }
  121. endbands = &lvl->bands[lvl->numbands];
  122. for (band = lvl->bands; band != endbands; ++band) {
  123. if (!band->data) {
  124. continue;
  125. }
  126. for (prcno = 0, prc = band->prcs; prcno < lvl->numprcs; ++prcno, ++prc) {
  127. if (!prc->cblks) {
  128. continue;
  129. }
  130. bmx = 0;
  131. endcblks = &prc->cblks[prc->numcblks];
  132. for (cblk = prc->cblks; cblk != endcblks; ++cblk) {
  133. mx = 0;
  134. for (i = 0; i < jas_matrix_numrows(cblk->data); ++i) {
  135. for (j = 0; j < jas_matrix_numcols(cblk->data); ++j) {
  136. v = abs(jas_matrix_get(cblk->data, i, j));
  137. if (v > mx) {
  138. mx = v;
  139. }
  140. }
  141. }
  142. if (mx > bmx) {
  143. bmx = mx;
  144. }
  145. cblk->numbps = JAS_MAX(jpc_firstone(mx) + 1 - JPC_NUMEXTRABITS, 0);
  146. }
  147. for (cblk = prc->cblks; cblk != endcblks; ++cblk) {
  148. cblk->numimsbs = band->numbps - cblk->numbps;
  149. assert(cblk->numimsbs >= 0);
  150. }
  151. for (cblk = prc->cblks; cblk != endcblks; ++cblk) {
  152. if (jpc_enc_enccblk(enc, cblk->stream, tcmpt, band, cblk)) {
  153. return -1;
  154. }
  155. }
  156. }
  157. }
  158. }
  159. }
  160. return 0;
  161. }
  162. int getthebyte(jas_stream_t *in, long off)
  163. {
  164. int c;
  165. long oldpos;
  166. oldpos = jas_stream_tell(in);
  167. assert(oldpos >= 0);
  168. jas_stream_seek(in, off, SEEK_SET);
  169. c = jas_stream_peekc(in);
  170. jas_stream_seek(in, oldpos, SEEK_SET);
  171. return c;
  172. }
  173. /* Encode a single code block. */
  174. int jpc_enc_enccblk(jpc_enc_t *enc, jas_stream_t *out, jpc_enc_tcmpt_t *tcmpt, jpc_enc_band_t *band, jpc_enc_cblk_t *cblk)
  175. {
  176. jpc_enc_pass_t *pass;
  177. jpc_enc_pass_t *endpasses;
  178. int bitpos;
  179. int n;
  180. int adjust;
  181. int ret;
  182. int passtype;
  183. int t;
  184. jpc_bitstream_t *bout;
  185. jpc_enc_pass_t *termpass;
  186. jpc_enc_rlvl_t *rlvl;
  187. int vcausal;
  188. int segsym;
  189. int termmode;
  190. int c;
  191. bout = 0;
  192. rlvl = band->rlvl;
  193. cblk->stream = jas_stream_memopen(0, 0);
  194. assert(cblk->stream);
  195. cblk->mqenc = jpc_mqenc_create(JPC_NUMCTXS, cblk->stream);
  196. assert(cblk->mqenc);
  197. jpc_mqenc_setctxs(cblk->mqenc, JPC_NUMCTXS, jpc_mqctxs);
  198. cblk->numpasses = (cblk->numbps > 0) ? (3 * cblk->numbps - 2) : 0;
  199. if (cblk->numpasses > 0) {
  200. cblk->passes = jas_alloc2(cblk->numpasses, sizeof(jpc_enc_pass_t));
  201. assert(cblk->passes);
  202. } else {
  203. cblk->passes = 0;
  204. }
  205. endpasses = &cblk->passes[cblk->numpasses];
  206. for (pass = cblk->passes; pass != endpasses; ++pass) {
  207. pass->start = 0;
  208. pass->end = 0;
  209. pass->term = JPC_ISTERMINATED(pass - cblk->passes, 0, cblk->numpasses, (tcmpt->cblksty & JPC_COX_TERMALL) != 0, (tcmpt->cblksty & JPC_COX_LAZY) != 0);
  210. pass->type = JPC_SEGTYPE(pass - cblk->passes, 0, (tcmpt->cblksty & JPC_COX_LAZY) != 0);
  211. pass->lyrno = -1;
  212. if (pass == endpasses - 1) {
  213. assert(pass->term == 1);
  214. pass->term = 1;
  215. }
  216. }
  217. cblk->flags = jas_matrix_create(jas_matrix_numrows(cblk->data) + 2,
  218. jas_matrix_numcols(cblk->data) + 2);
  219. assert(cblk->flags);
  220. bitpos = cblk->numbps - 1;
  221. pass = cblk->passes;
  222. n = cblk->numpasses;
  223. while (--n >= 0) {
  224. if (pass->type == JPC_SEG_MQ) {
  225. /* NOP */
  226. } else {
  227. assert(pass->type == JPC_SEG_RAW);
  228. if (!bout) {
  229. bout = jpc_bitstream_sopen(cblk->stream, "w");
  230. assert(bout);
  231. }
  232. }
  233. #if 1
  234. passtype = (pass - cblk->passes + 2) % 3;
  235. #else
  236. passtype = JPC_PASSTYPE(pass - cblk->passes + 2);
  237. #endif
  238. pass->start = jas_stream_tell(cblk->stream);
  239. #if 0
  240. assert(jas_stream_tell(cblk->stream) == jas_stream_getrwcount(cblk->stream));
  241. #endif
  242. assert(bitpos >= 0);
  243. vcausal = (tcmpt->cblksty & JPC_COX_VSC) != 0;
  244. segsym = (tcmpt->cblksty & JPC_COX_SEGSYM) != 0;
  245. if (pass->term) {
  246. termmode = ((tcmpt->cblksty & JPC_COX_PTERM) ?
  247. JPC_MQENC_PTERM : JPC_MQENC_DEFTERM) + 1;
  248. } else {
  249. termmode = 0;
  250. }
  251. switch (passtype) {
  252. case JPC_SIGPASS:
  253. ret = (pass->type == JPC_SEG_MQ) ? jpc_encsigpass(cblk->mqenc,
  254. bitpos, band->orient, vcausal, cblk->flags,
  255. cblk->data, termmode, &pass->nmsedec) :
  256. jpc_encrawsigpass(bout, bitpos, vcausal, cblk->flags,
  257. cblk->data, termmode, &pass->nmsedec);
  258. break;
  259. case JPC_REFPASS:
  260. ret = (pass->type == JPC_SEG_MQ) ? jpc_encrefpass(cblk->mqenc,
  261. bitpos, vcausal, cblk->flags, cblk->data, termmode,
  262. &pass->nmsedec) : jpc_encrawrefpass(bout, bitpos,
  263. vcausal, cblk->flags, cblk->data, termmode,
  264. &pass->nmsedec);
  265. break;
  266. case JPC_CLNPASS:
  267. assert(pass->type == JPC_SEG_MQ);
  268. ret = jpc_encclnpass(cblk->mqenc, bitpos, band->orient,
  269. vcausal, segsym, cblk->flags, cblk->data, termmode,
  270. &pass->nmsedec);
  271. break;
  272. default:
  273. assert(0);
  274. break;
  275. }
  276. if (pass->type == JPC_SEG_MQ) {
  277. if (pass->term) {
  278. jpc_mqenc_init(cblk->mqenc);
  279. }
  280. jpc_mqenc_getstate(cblk->mqenc, &pass->mqencstate);
  281. pass->end = jas_stream_tell(cblk->stream);
  282. if (tcmpt->cblksty & JPC_COX_RESET) {
  283. jpc_mqenc_setctxs(cblk->mqenc, JPC_NUMCTXS, jpc_mqctxs);
  284. }
  285. } else {
  286. if (pass->term) {
  287. if (jpc_bitstream_pending(bout)) {
  288. jpc_bitstream_outalign(bout, 0x2a);
  289. }
  290. jpc_bitstream_close(bout);
  291. bout = 0;
  292. pass->end = jas_stream_tell(cblk->stream);
  293. } else {
  294. pass->end = jas_stream_tell(cblk->stream) +
  295. jpc_bitstream_pending(bout);
  296. /* NOTE - This will not work. need to adjust by # of pending output bytes */
  297. }
  298. }
  299. #if 0
  300. /* XXX - This assertion fails sometimes when various coding modes are used.
  301. This seems to be harmless, but why does it happen at all? */
  302. assert(jas_stream_tell(cblk->stream) == jas_stream_getrwcount(cblk->stream));
  303. #endif
  304. pass->wmsedec = jpc_fixtodbl(band->rlvl->tcmpt->synweight) *
  305. jpc_fixtodbl(band->rlvl->tcmpt->synweight) *
  306. jpc_fixtodbl(band->synweight) *
  307. jpc_fixtodbl(band->synweight) *
  308. jpc_fixtodbl(band->absstepsize) * jpc_fixtodbl(band->absstepsize) *
  309. ((double) (1 << bitpos)) * ((double)(1 << bitpos)) *
  310. jpc_fixtodbl(pass->nmsedec);
  311. pass->cumwmsedec = pass->wmsedec;
  312. if (pass != cblk->passes) {
  313. pass->cumwmsedec += pass[-1].cumwmsedec;
  314. }
  315. if (passtype == JPC_CLNPASS) {
  316. --bitpos;
  317. }
  318. ++pass;
  319. }
  320. #if 0
  321. dump_passes(cblk->passes, cblk->numpasses, cblk);
  322. #endif
  323. n = 0;
  324. endpasses = &cblk->passes[cblk->numpasses];
  325. for (pass = cblk->passes; pass != endpasses; ++pass) {
  326. if (pass->start < n) {
  327. pass->start = n;
  328. }
  329. if (pass->end < n) {
  330. pass->end = n;
  331. }
  332. if (!pass->term) {
  333. termpass = pass;
  334. while (termpass - pass < cblk->numpasses &&
  335. !termpass->term) {
  336. ++termpass;
  337. }
  338. if (pass->type == JPC_SEG_MQ) {
  339. t = (pass->mqencstate.lastbyte == 0xff) ? 1 : 0;
  340. if (pass->mqencstate.ctreg >= 5) {
  341. adjust = 4 + t;
  342. } else {
  343. adjust = 5 + t;
  344. }
  345. pass->end += adjust;
  346. }
  347. if (pass->end > termpass->end) {
  348. pass->end = termpass->end;
  349. }
  350. if ((c = getthebyte(cblk->stream, pass->end - 1)) == EOF) {
  351. abort();
  352. }
  353. if (c == 0xff) {
  354. ++pass->end;
  355. }
  356. n = JAS_MAX(n, pass->end);
  357. } else {
  358. n = JAS_MAX(n, pass->end);
  359. }
  360. }
  361. #if 0
  362. dump_passes(cblk->passes, cblk->numpasses, cblk);
  363. #endif
  364. if (bout) {
  365. jpc_bitstream_close(bout);
  366. }
  367. return 0;
  368. }
  369. /******************************************************************************\
  370. * Code for significance pass.
  371. \******************************************************************************/
  372. #define sigpass_step(fp, frowstep, dp, bitpos, one, nmsedec, orient, mqenc, vcausalflag) \
  373. { \
  374. int f; \
  375. int v; \
  376. f = *(fp); \
  377. if ((f & JPC_OTHSIGMSK) && !(f & (JPC_SIG | JPC_VISIT))) { \
  378. v = (abs(*(dp)) & (one)) ? 1 : 0; \
  379. jpc_mqenc_setcurctx(mqenc, JPC_GETZCCTXNO(f, (orient))); \
  380. jpc_mqenc_putbit(mqenc, v); \
  381. if (v) { \
  382. *(nmsedec) += JPC_GETSIGNMSEDEC(abs(*(dp)), (bitpos) + JPC_NUMEXTRABITS); \
  383. v = ((*(dp) < 0) ? 1 : 0); \
  384. jpc_mqenc_setcurctx(mqenc, JPC_GETSCCTXNO(f)); \
  385. jpc_mqenc_putbit(mqenc, v ^ JPC_GETSPB(f)); \
  386. JPC_UPDATEFLAGS4(fp, frowstep, v, vcausalflag); \
  387. *(fp) |= JPC_SIG; \
  388. } \
  389. *(fp) |= JPC_VISIT; \
  390. } \
  391. }
  392. static int jpc_encsigpass(jpc_mqenc_t *mqenc, int bitpos, int orient, int vcausalflag,
  393. jas_matrix_t *flags, jas_matrix_t *data, int term, long *nmsedec)
  394. {
  395. int i;
  396. int j;
  397. int one;
  398. int vscanlen;
  399. int width;
  400. int height;
  401. int frowstep;
  402. int drowstep;
  403. int fstripestep;
  404. int dstripestep;
  405. jpc_fix_t *fstripestart;
  406. jpc_fix_t *dstripestart;
  407. jpc_fix_t *fp;
  408. jpc_fix_t *dp;
  409. jpc_fix_t *fvscanstart;
  410. jpc_fix_t *dvscanstart;
  411. int k;
  412. *nmsedec = 0;
  413. width = jas_matrix_numcols(data);
  414. height = jas_matrix_numrows(data);
  415. frowstep = jas_matrix_rowstep(flags);
  416. drowstep = jas_matrix_rowstep(data);
  417. fstripestep = frowstep << 2;
  418. dstripestep = drowstep << 2;
  419. one = 1 << (bitpos + JPC_NUMEXTRABITS);
  420. fstripestart = jas_matrix_getref(flags, 1, 1);
  421. dstripestart = jas_matrix_getref(data, 0, 0);
  422. for (i = height; i > 0; i -= 4, fstripestart += fstripestep,
  423. dstripestart += dstripestep) {
  424. fvscanstart = fstripestart;
  425. dvscanstart = dstripestart;
  426. vscanlen = JAS_MIN(i, 4);
  427. for (j = width; j > 0; --j, ++fvscanstart, ++dvscanstart) {
  428. fp = fvscanstart;
  429. dp = dvscanstart;
  430. k = vscanlen;
  431. sigpass_step(fp, frowstep, dp, bitpos, one,
  432. nmsedec, orient, mqenc, vcausalflag);
  433. if (--k <= 0) {
  434. continue;
  435. }
  436. fp += frowstep;
  437. dp += drowstep;
  438. sigpass_step(fp, frowstep, dp, bitpos, one,
  439. nmsedec, orient, mqenc, 0);
  440. if (--k <= 0) {
  441. continue;
  442. }
  443. fp += frowstep;
  444. dp += drowstep;
  445. sigpass_step(fp, frowstep, dp, bitpos, one,
  446. nmsedec, orient, mqenc, 0);
  447. if (--k <= 0) {
  448. continue;
  449. }
  450. fp += frowstep;
  451. dp += drowstep;
  452. sigpass_step(fp, frowstep, dp, bitpos, one,
  453. nmsedec, orient, mqenc, 0);
  454. }
  455. }
  456. if (term) {
  457. jpc_mqenc_flush(mqenc, term - 1);
  458. }
  459. return jpc_mqenc_error(mqenc) ? (-1) : 0;
  460. }
  461. #define rawsigpass_step(fp, frowstep, dp, bitpos, one, nmsedec, out, vcausalflag) \
  462. { \
  463. jpc_fix_t f = *(fp); \
  464. jpc_fix_t v; \
  465. if ((f & JPC_OTHSIGMSK) && !(f & (JPC_SIG | JPC_VISIT))) { \
  466. v = (abs(*(dp)) & (one)) ? 1 : 0; \
  467. if ((jpc_bitstream_putbit((out), v)) == EOF) { \
  468. return -1; \
  469. } \
  470. if (v) { \
  471. *(nmsedec) += JPC_GETSIGNMSEDEC(abs(*(dp)), (bitpos) + JPC_NUMEXTRABITS); \
  472. v = ((*(dp) < 0) ? 1 : 0); \
  473. if (jpc_bitstream_putbit(out, v) == EOF) { \
  474. return -1; \
  475. } \
  476. JPC_UPDATEFLAGS4(fp, frowstep, v, vcausalflag); \
  477. *(fp) |= JPC_SIG; \
  478. } \
  479. *(fp) |= JPC_VISIT; \
  480. } \
  481. }
  482. static int jpc_encrawsigpass(jpc_bitstream_t *out, int bitpos, int vcausalflag, jas_matrix_t *flags,
  483. jas_matrix_t *data, int term, long *nmsedec)
  484. {
  485. int i;
  486. int j;
  487. int k;
  488. int one;
  489. int vscanlen;
  490. int width;
  491. int height;
  492. int frowstep;
  493. int drowstep;
  494. int fstripestep;
  495. int dstripestep;
  496. jpc_fix_t *fstripestart;
  497. jpc_fix_t *dstripestart;
  498. jpc_fix_t *fp;
  499. jpc_fix_t *dp;
  500. jpc_fix_t *fvscanstart;
  501. jpc_fix_t *dvscanstart;
  502. *nmsedec = 0;
  503. width = jas_matrix_numcols(data);
  504. height = jas_matrix_numrows(data);
  505. frowstep = jas_matrix_rowstep(flags);
  506. drowstep = jas_matrix_rowstep(data);
  507. fstripestep = frowstep << 2;
  508. dstripestep = drowstep << 2;
  509. one = 1 << (bitpos + JPC_NUMEXTRABITS);
  510. fstripestart = jas_matrix_getref(flags, 1, 1);
  511. dstripestart = jas_matrix_getref(data, 0, 0);
  512. for (i = height; i > 0; i -= 4, fstripestart += fstripestep,
  513. dstripestart += dstripestep) {
  514. fvscanstart = fstripestart;
  515. dvscanstart = dstripestart;
  516. vscanlen = JAS_MIN(i, 4);
  517. for (j = width; j > 0; --j, ++fvscanstart, ++dvscanstart) {
  518. fp = fvscanstart;
  519. dp = dvscanstart;
  520. k = vscanlen;
  521. rawsigpass_step(fp, frowstep, dp, bitpos, one,
  522. nmsedec, out, vcausalflag);
  523. if (--k <= 0) {
  524. continue;
  525. }
  526. fp += frowstep;
  527. dp += drowstep;
  528. rawsigpass_step(fp, frowstep, dp, bitpos, one,
  529. nmsedec, out, 0);
  530. if (--k <= 0) {
  531. continue;
  532. }
  533. fp += frowstep;
  534. dp += drowstep;
  535. rawsigpass_step(fp, frowstep, dp, bitpos, one,
  536. nmsedec, out, 0);
  537. if (--k <= 0) {
  538. continue;
  539. }
  540. fp += frowstep;
  541. dp += drowstep;
  542. rawsigpass_step(fp, frowstep, dp, bitpos, one,
  543. nmsedec, out, 0);
  544. if (--k <= 0) {
  545. continue;
  546. }
  547. fp += frowstep;
  548. dp += drowstep;
  549. }
  550. }
  551. if (term) {
  552. jpc_bitstream_outalign(out, 0x2a);
  553. }
  554. return 0;
  555. }
  556. /******************************************************************************\
  557. * Code for refinement pass.
  558. \******************************************************************************/
  559. #define refpass_step(fp, dp, bitpos, one, nmsedec, mqenc, vcausalflag) \
  560. { \
  561. int v; \
  562. if (((*(fp)) & (JPC_SIG | JPC_VISIT)) == JPC_SIG) { \
  563. (d) = *(dp); \
  564. *(nmsedec) += JPC_GETREFNMSEDEC(abs(d), (bitpos) + JPC_NUMEXTRABITS); \
  565. jpc_mqenc_setcurctx((mqenc), JPC_GETMAGCTXNO(*(fp))); \
  566. v = (abs(d) & (one)) ? 1 : 0; \
  567. jpc_mqenc_putbit((mqenc), v); \
  568. *(fp) |= JPC_REFINE; \
  569. } \
  570. }
  571. static int jpc_encrefpass(jpc_mqenc_t *mqenc, int bitpos, int vcausalflag, jas_matrix_t *flags, jas_matrix_t *data,
  572. int term, long *nmsedec)
  573. {
  574. int i;
  575. int j;
  576. int one;
  577. int vscanlen;
  578. int d;
  579. int width;
  580. int height;
  581. int frowstep;
  582. int drowstep;
  583. int fstripestep;
  584. int dstripestep;
  585. jpc_fix_t *fstripestart;
  586. jpc_fix_t *dstripestart;
  587. jpc_fix_t *fvscanstart;
  588. jpc_fix_t *dvscanstart;
  589. jpc_fix_t *dp;
  590. jpc_fix_t *fp;
  591. int k;
  592. *nmsedec = 0;
  593. width = jas_matrix_numcols(data);
  594. height = jas_matrix_numrows(data);
  595. frowstep = jas_matrix_rowstep(flags);
  596. drowstep = jas_matrix_rowstep(data);
  597. fstripestep = frowstep << 2;
  598. dstripestep = drowstep << 2;
  599. one = 1 << (bitpos + JPC_NUMEXTRABITS);
  600. fstripestart = jas_matrix_getref(flags, 1, 1);
  601. dstripestart = jas_matrix_getref(data, 0, 0);
  602. for (i = height; i > 0; i -= 4, fstripestart += fstripestep,
  603. dstripestart += dstripestep) {
  604. fvscanstart = fstripestart;
  605. dvscanstart = dstripestart;
  606. vscanlen = JAS_MIN(i, 4);
  607. for (j = width; j > 0; --j, ++fvscanstart, ++dvscanstart) {
  608. fp = fvscanstart;
  609. dp = dvscanstart;
  610. k = vscanlen;
  611. refpass_step(fp, dp, bitpos, one, nmsedec,
  612. mqenc, vcausalflag);
  613. if (--k <= 0) {
  614. continue;
  615. }
  616. fp += frowstep;
  617. dp += drowstep;
  618. refpass_step(fp, dp, bitpos, one, nmsedec,
  619. mqenc, 0);
  620. if (--k <= 0) {
  621. continue;
  622. }
  623. fp += frowstep;
  624. dp += drowstep;
  625. refpass_step(fp, dp, bitpos, one, nmsedec,
  626. mqenc, 0);
  627. if (--k <= 0) {
  628. continue;
  629. }
  630. fp += frowstep;
  631. dp += drowstep;
  632. refpass_step(fp, dp, bitpos, one, nmsedec,
  633. mqenc, 0);
  634. }
  635. }
  636. if (term) {
  637. jpc_mqenc_flush(mqenc, term - 1);
  638. }
  639. return jpc_mqenc_error(mqenc) ? (-1) : 0;
  640. }
  641. #define rawrefpass_step(fp, dp, bitpos, one, nmsedec, out, vcausalflag) \
  642. { \
  643. jpc_fix_t d; \
  644. jpc_fix_t v; \
  645. if (((*(fp)) & (JPC_SIG | JPC_VISIT)) == JPC_SIG) { \
  646. d = *(dp); \
  647. *(nmsedec) += JPC_GETREFNMSEDEC(abs(d), (bitpos) + JPC_NUMEXTRABITS); \
  648. v = (abs(d) & (one)) ? 1 : 0; \
  649. if (jpc_bitstream_putbit((out), v) == EOF) { \
  650. return -1; \
  651. } \
  652. *(fp) |= JPC_REFINE; \
  653. } \
  654. }
  655. static int jpc_encrawrefpass(jpc_bitstream_t *out, int bitpos, int vcausalflag, jas_matrix_t *flags,
  656. jas_matrix_t *data, int term, long *nmsedec)
  657. {
  658. int i;
  659. int j;
  660. int k;
  661. int one;
  662. int vscanlen;
  663. int width;
  664. int height;
  665. int frowstep;
  666. int drowstep;
  667. int fstripestep;
  668. int dstripestep;
  669. jpc_fix_t *fstripestart;
  670. jpc_fix_t *dstripestart;
  671. jpc_fix_t *fvscanstart;
  672. jpc_fix_t *dvscanstart;
  673. jpc_fix_t *dp;
  674. jpc_fix_t *fp;
  675. *nmsedec = 0;
  676. width = jas_matrix_numcols(data);
  677. height = jas_matrix_numrows(data);
  678. frowstep = jas_matrix_rowstep(flags);
  679. drowstep = jas_matrix_rowstep(data);
  680. fstripestep = frowstep << 2;
  681. dstripestep = drowstep << 2;
  682. one = 1 << (bitpos + JPC_NUMEXTRABITS);
  683. fstripestart = jas_matrix_getref(flags, 1, 1);
  684. dstripestart = jas_matrix_getref(data, 0, 0);
  685. for (i = height; i > 0; i -= 4, fstripestart += fstripestep,
  686. dstripestart += dstripestep) {
  687. fvscanstart = fstripestart;
  688. dvscanstart = dstripestart;
  689. vscanlen = JAS_MIN(i, 4);
  690. for (j = width; j > 0; --j, ++fvscanstart, ++dvscanstart) {
  691. fp = fvscanstart;
  692. dp = dvscanstart;
  693. k = vscanlen;
  694. rawrefpass_step(fp, dp, bitpos, one, nmsedec,
  695. out, vcausalflag);
  696. if (--k <= 0) {
  697. continue;
  698. }
  699. fp += frowstep;
  700. dp += drowstep;
  701. rawrefpass_step(fp, dp, bitpos, one, nmsedec,
  702. out, vcausalflag);
  703. if (--k <= 0) {
  704. continue;
  705. }
  706. fp += frowstep;
  707. dp += drowstep;
  708. rawrefpass_step(fp, dp, bitpos, one, nmsedec,
  709. out, vcausalflag);
  710. if (--k <= 0) {
  711. continue;
  712. }
  713. fp += frowstep;
  714. dp += drowstep;
  715. rawrefpass_step(fp, dp, bitpos, one, nmsedec,
  716. out, vcausalflag);
  717. }
  718. }
  719. if (term) {
  720. jpc_bitstream_outalign(out, 0x2a);
  721. }
  722. return 0;
  723. }
  724. /******************************************************************************\
  725. * Code for cleanup pass.
  726. \******************************************************************************/
  727. #define clnpass_step(fp, frowstep, dp, bitpos, one, orient, nmsedec, mqenc, label1, label2, vcausalflag) \
  728. { \
  729. int f; \
  730. int v; \
  731. label1 \
  732. f = *(fp); \
  733. if (!(f & (JPC_SIG | JPC_VISIT))) { \
  734. jpc_mqenc_setcurctx(mqenc, JPC_GETZCCTXNO(f, (orient))); \
  735. v = (abs(*(dp)) & (one)) ? 1 : 0; \
  736. jpc_mqenc_putbit((mqenc), v); \
  737. if (v) { \
  738. label2 \
  739. f = *(fp); \
  740. /* Coefficient is significant. */ \
  741. *(nmsedec) += JPC_GETSIGNMSEDEC(abs(*(dp)), (bitpos) + JPC_NUMEXTRABITS); \
  742. jpc_mqenc_setcurctx((mqenc), JPC_GETSCCTXNO(f)); \
  743. v = ((*(dp) < 0) ? 1 : 0); \
  744. jpc_mqenc_putbit((mqenc), v ^ JPC_GETSPB(f)); \
  745. JPC_UPDATEFLAGS4((fp), (frowstep), v, vcausalflag); \
  746. *(fp) |= JPC_SIG; \
  747. } \
  748. } \
  749. *(fp) &= ~JPC_VISIT; \
  750. }
  751. static int jpc_encclnpass(jpc_mqenc_t *mqenc, int bitpos, int orient, int vcausalflag, int segsymflag, jas_matrix_t *flags,
  752. jas_matrix_t *data, int term, long *nmsedec)
  753. {
  754. int i;
  755. int j;
  756. int k;
  757. int vscanlen;
  758. int v;
  759. int runlen;
  760. jpc_fix_t *fp;
  761. int width;
  762. int height;
  763. jpc_fix_t *dp;
  764. int one;
  765. int frowstep;
  766. int drowstep;
  767. int fstripestep;
  768. int dstripestep;
  769. jpc_fix_t *fstripestart;
  770. jpc_fix_t *dstripestart;
  771. jpc_fix_t *fvscanstart;
  772. jpc_fix_t *dvscanstart;
  773. *nmsedec = 0;
  774. width = jas_matrix_numcols(data);
  775. height = jas_matrix_numrows(data);
  776. frowstep = jas_matrix_rowstep(flags);
  777. drowstep = jas_matrix_rowstep(data);
  778. fstripestep = frowstep << 2;
  779. dstripestep = drowstep << 2;
  780. one = 1 << (bitpos + JPC_NUMEXTRABITS);
  781. fstripestart = jas_matrix_getref(flags, 1, 1);
  782. dstripestart = jas_matrix_getref(data, 0, 0);
  783. for (i = height; i > 0; i -= 4, fstripestart += fstripestep,
  784. dstripestart += dstripestep) {
  785. fvscanstart = fstripestart;
  786. dvscanstart = dstripestart;
  787. vscanlen = JAS_MIN(i, 4);
  788. for (j = width; j > 0; --j, ++fvscanstart, ++dvscanstart) {
  789. fp = fvscanstart;
  790. if (vscanlen >= 4 && !((*fp) & (JPC_SIG | JPC_VISIT |
  791. JPC_OTHSIGMSK)) && (fp += frowstep, !((*fp) & (JPC_SIG |
  792. JPC_VISIT | JPC_OTHSIGMSK))) && (fp += frowstep, !((*fp) &
  793. (JPC_SIG | JPC_VISIT | JPC_OTHSIGMSK))) && (fp += frowstep,
  794. !((*fp) & (JPC_SIG | JPC_VISIT | JPC_OTHSIGMSK)))) {
  795. dp = dvscanstart;
  796. for (k = 0; k < vscanlen; ++k) {
  797. v = (abs(*dp) & one) ? 1 : 0;
  798. if (v) {
  799. break;
  800. }
  801. dp += drowstep;
  802. }
  803. runlen = k;
  804. if (runlen >= 4) {
  805. jpc_mqenc_setcurctx(mqenc, JPC_AGGCTXNO);
  806. jpc_mqenc_putbit(mqenc, 0);
  807. continue;
  808. }
  809. jpc_mqenc_setcurctx(mqenc, JPC_AGGCTXNO);
  810. jpc_mqenc_putbit(mqenc, 1);
  811. jpc_mqenc_setcurctx(mqenc, JPC_UCTXNO);
  812. jpc_mqenc_putbit(mqenc, runlen >> 1);
  813. jpc_mqenc_putbit(mqenc, runlen & 1);
  814. fp = fvscanstart + frowstep * runlen;
  815. dp = dvscanstart + drowstep * runlen;
  816. k = vscanlen - runlen;
  817. switch (runlen) {
  818. case 0:
  819. goto clnpass_partial0;
  820. break;
  821. case 1:
  822. goto clnpass_partial1;
  823. break;
  824. case 2:
  825. goto clnpass_partial2;
  826. break;
  827. case 3:
  828. goto clnpass_partial3;
  829. break;
  830. }
  831. } else {
  832. runlen = 0;
  833. fp = fvscanstart;
  834. dp = dvscanstart;
  835. k = vscanlen;
  836. goto clnpass_full0;
  837. }
  838. clnpass_step(fp, frowstep, dp, bitpos, one,
  839. orient, nmsedec, mqenc, clnpass_full0:, clnpass_partial0:, vcausalflag);
  840. if (--k <= 0) {
  841. continue;
  842. }
  843. fp += frowstep;
  844. dp += drowstep;
  845. clnpass_step(fp, frowstep, dp, bitpos, one,
  846. orient, nmsedec, mqenc, ;, clnpass_partial1:, 0);
  847. if (--k <= 0) {
  848. continue;
  849. }
  850. fp += frowstep;
  851. dp += drowstep;
  852. clnpass_step(fp, frowstep, dp, bitpos, one,
  853. orient, nmsedec, mqenc, ;, clnpass_partial2:, 0);
  854. if (--k <= 0) {
  855. continue;
  856. }
  857. fp += frowstep;
  858. dp += drowstep;
  859. clnpass_step(fp, frowstep, dp, bitpos, one,
  860. orient, nmsedec, mqenc, ;, clnpass_partial3:, 0);
  861. }
  862. }
  863. if (segsymflag) {
  864. jpc_mqenc_setcurctx(mqenc, JPC_UCTXNO);
  865. jpc_mqenc_putbit(mqenc, 1);
  866. jpc_mqenc_putbit(mqenc, 0);
  867. jpc_mqenc_putbit(mqenc, 1);
  868. jpc_mqenc_putbit(mqenc, 0);
  869. }
  870. if (term) {
  871. jpc_mqenc_flush(mqenc, term - 1);
  872. }
  873. return jpc_mqenc_error(mqenc) ? (-1) : 0;
  874. }