Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

963 lines
23 KiB

  1. /*++
  2. Copyright (c) 1996 Microsoft Corporation
  3. Module Name:
  4. decode.c
  5. Abstract:
  6. This file contains functions for decoding (de-compressing)
  7. compressed 1 bit per pel data from a TIFF data
  8. stream. The supported compression algorithms are
  9. as follows:
  10. o Uncompressed (raw)
  11. o One dimensional - MH or Modified Huffman
  12. o Two dimensional - MR or Modified Read
  13. Environment:
  14. WIN32 User Mode
  15. Author:
  16. Wesley Witt (wesw) 17-Feb-1996
  17. --*/
  18. #include "tifflibp.h"
  19. #pragma hdrstop
  20. BOOL
  21. DecodeUnCompressedFaxData(
  22. PTIFF_INSTANCE_DATA TiffInstance,
  23. LPBYTE OutputBuffer,
  24. BOOL SingleLineBuffer,
  25. DWORD PadLength
  26. )
  27. /*++
  28. Routine Description:
  29. Decode a single page of uncompressed TIFF data.
  30. Arguments:
  31. TiffInstance - Pointer to the TIFF instance data
  32. OutputBuffer - Output buffer where the uncompressed data
  33. is written. This buffer must be allocated
  34. by the caller and must be large enough for
  35. a single page of data.
  36. Return Value:
  37. NONE
  38. --*/
  39. {
  40. __try {
  41. FillMemory( OutputBuffer, TiffInstance->ImageHeight * (TiffInstance->ImageWidth / 8), WHITE );
  42. } __except (EXCEPTION_EXECUTE_HANDLER) {
  43. return FALSE;
  44. }
  45. TiffInstance->Lines = TiffInstance->StripDataSize / (TiffInstance->ImageWidth / 8);
  46. CopyMemory( OutputBuffer, TiffInstance->StripData, TiffInstance->StripDataSize );
  47. return TRUE;
  48. }
  49. BOOL
  50. DecodeMHFaxData(
  51. PTIFF_INSTANCE_DATA TiffInstance,
  52. LPBYTE OutputBuffer,
  53. BOOL SingleLineBuffer,
  54. DWORD PadLength
  55. )
  56. /*++
  57. Routine Description:
  58. Decode a single page of 1 dimensionaly compressed
  59. TIFF data.
  60. Arguments:
  61. TiffInstance - Pointer to the TIFF instance data
  62. OutputBuffer - Output buffer where the uncompressed data
  63. is written. This buffer must be allocated
  64. by the caller and must be large enough for
  65. a single page of data.
  66. Return Value:
  67. NONE
  68. --*/
  69. {
  70. DWORD i;
  71. DWORD j;
  72. BYTE octet;
  73. PDECODE_TREE Tree;
  74. INT code;
  75. PBYTE plinebuf;
  76. DWORD lineWidth;
  77. DWORD Lines;
  78. DWORD EolCount;
  79. DWORD BadFaxLines;
  80. BOOL LastLineBad;
  81. //
  82. // initialization
  83. //
  84. if (!SingleLineBuffer) {
  85. __try {
  86. FillMemory( OutputBuffer, TiffInstance->ImageHeight * (TiffInstance->ImageWidth / 8), WHITE );
  87. } __except (EXCEPTION_EXECUTE_HANDLER) {
  88. return FALSE;
  89. }
  90. }
  91. Tree = WhiteDecodeTree;
  92. code = 0;
  93. Lines = 0;
  94. EolCount = 1;
  95. BadFaxLines = 0;
  96. LastLineBad = FALSE;
  97. TiffInstance->Color = 0;
  98. TiffInstance->RunLength = 0;
  99. TiffInstance->bitdata = 0;
  100. TiffInstance->bitcnt = DWORDBITS;
  101. TiffInstance->bitbuf = OutputBuffer;
  102. TiffInstance->StartGood = 0;
  103. TiffInstance->EndGood = 0;
  104. plinebuf = TiffInstance->StripData;
  105. lineWidth = TiffInstance->ImageWidth;
  106. for (i=0; i<TiffInstance->StripDataSize; i++) {
  107. if (plinebuf[i] == 0) {
  108. break;
  109. }
  110. }
  111. //
  112. // loop thru each byte in the file
  113. //
  114. for (; i<TiffInstance->StripDataSize; i++) {
  115. octet = plinebuf[i];
  116. if (i == 2147) DebugBreak();
  117. //
  118. // loop thru each bit in the byte
  119. //
  120. for (j=0; j<8; j++,octet<<=1) {
  121. if (code == DECODEEOL) {
  122. if (!(octet&0x80)) {
  123. //
  124. // here we skip all bits until we hit a 1 bit
  125. // this happens when the first octet in a line
  126. // is all zeroes and we detect that we are
  127. // searching for an EOL
  128. //
  129. continue;
  130. }
  131. if (TiffInstance->RunLength && TiffInstance->RunLength != lineWidth) {
  132. if (TiffInstance->RunLength < lineWidth) {
  133. TiffInstance->Color = 0;
  134. OutputCodeBits( TiffInstance, lineWidth - TiffInstance->RunLength );
  135. }
  136. if (LastLineBad) {
  137. BadFaxLines += 1;
  138. } else {
  139. if (BadFaxLines > TiffInstance->BadFaxLines) {
  140. TiffInstance->BadFaxLines = BadFaxLines;
  141. }
  142. BadFaxLines = 1;
  143. LastLineBad = TRUE;
  144. }
  145. } else {
  146. LastLineBad = FALSE;
  147. }
  148. if (!TiffInstance->StartGood) {
  149. TiffInstance->StartGood = i - 1;
  150. }
  151. //
  152. // we hit the eol marker
  153. //
  154. Tree = WhiteDecodeTree;
  155. TiffInstance->Color = 0;
  156. code = 0;
  157. if (SingleLineBuffer) {
  158. TiffInstance->bitbuf = OutputBuffer;
  159. }
  160. if (TiffInstance->RunLength) {
  161. FlushLine(TiffInstance,PadLength);
  162. TiffInstance->RunLength = 0;
  163. Lines += 1;
  164. EolCount = 1;
  165. } else {
  166. //
  167. // the eol count is maintained to that
  168. // an rtc sequence is detected.
  169. //
  170. EolCount += 1;
  171. if (EolCount == 6) {
  172. //
  173. // this is an rtc sequence, so any
  174. // data that follows in the file
  175. // is garbage.
  176. //
  177. goto good_exit;
  178. }
  179. }
  180. continue;
  181. }
  182. code = ((octet&0x80)>>7) ? Tree[code].Right : Tree[code].Left;
  183. if (code == BADRUN) {
  184. return FALSE;
  185. }
  186. if (code < 1) {
  187. code = (-code);
  188. OutputCodeBits( TiffInstance, code );
  189. if (code < 64) {
  190. //
  191. // terminating code
  192. //
  193. TiffInstance->Color = !TiffInstance->Color;
  194. Tree = TiffInstance->Color ? BlackDecodeTree : WhiteDecodeTree;
  195. }
  196. code = 0;
  197. }
  198. }
  199. }
  200. good_exit:
  201. TiffInstance->EndGood = i;
  202. if (BadFaxLines > TiffInstance->BadFaxLines) {
  203. TiffInstance->BadFaxLines = BadFaxLines;
  204. }
  205. FlushBits( TiffInstance );
  206. TiffInstance->Lines = Lines;
  207. return TRUE;
  208. }
  209. BOOL
  210. DecodeMRFaxData(
  211. PTIFF_INSTANCE_DATA TiffInstance,
  212. LPBYTE OutputBuffer,
  213. BOOL SingleLineBuffer,
  214. DWORD PadLength
  215. )
  216. /*++
  217. Routine Description:
  218. Decode a single page of 2 dimensionaly compressed
  219. TIFF data.
  220. Arguments:
  221. TiffInstance - Pointer to the TIFF instance data
  222. OutputBuffer - Output buffer where the uncompressed data
  223. is written. This buffer must be allocated
  224. by the caller and must be large enough for
  225. a single page of data.
  226. Return Value:
  227. NONE
  228. --*/
  229. {
  230. DWORD i;
  231. DWORD j;
  232. BYTE octet;
  233. PDECODE_TREE Tree;
  234. INT code;
  235. LPBYTE prefline;
  236. LPBYTE pcurrline;
  237. DWORD HorzRuns;
  238. BOOL OneDimensional;
  239. DWORD a0;
  240. DWORD a1;
  241. DWORD b1;
  242. DWORD b2;
  243. PBYTE plinebuf;
  244. DWORD lineWidth;
  245. DWORD Lines;
  246. DWORD EolCount;
  247. DWORD BadFaxLines;
  248. BOOL LastLineBad;
  249. //
  250. // initialization
  251. //
  252. if (!SingleLineBuffer) {
  253. __try {
  254. FillMemory( OutputBuffer, TiffInstance->ImageHeight * (TiffInstance->ImageWidth / 8), WHITE );
  255. } __except (EXCEPTION_EXECUTE_HANDLER) {
  256. return FALSE;
  257. }
  258. }
  259. Tree = WhiteDecodeTree;
  260. code = 0;
  261. HorzRuns = 0;
  262. EolCount = 1;
  263. BadFaxLines = 0;
  264. LastLineBad = FALSE;
  265. TiffInstance->Color = 0;
  266. TiffInstance->RunLength = 0;
  267. TiffInstance->bitdata = 0;
  268. TiffInstance->bitcnt = DWORDBITS;
  269. TiffInstance->bitbuf = OutputBuffer;
  270. OneDimensional = TRUE;
  271. plinebuf = TiffInstance->StripData;
  272. lineWidth = TiffInstance->ImageWidth;
  273. pcurrline = OutputBuffer;
  274. prefline = OutputBuffer;
  275. a0 = 0;
  276. a1 = 0;
  277. b1 = 0;
  278. b2 = 0;
  279. Lines = 0;
  280. //
  281. // loop thru each byte in the file
  282. //
  283. for (j=0; j<TiffInstance->StripDataSize; j++) {
  284. octet = *plinebuf++;
  285. //
  286. // loop thru each bit in the byte
  287. //
  288. for (i=0; i<8; i++,octet<<=1) {
  289. if (code == DECODEEOL2) {
  290. //
  291. // we hit the final eol marker
  292. //
  293. if (TiffInstance->RunLength && TiffInstance->RunLength != lineWidth) {
  294. if (TiffInstance->RunLength < lineWidth) {
  295. TiffInstance->Color = 0;
  296. OutputCodeBits( TiffInstance, lineWidth - TiffInstance->RunLength );
  297. }
  298. if (LastLineBad) {
  299. BadFaxLines += 1;
  300. } else {
  301. if (BadFaxLines > TiffInstance->BadFaxLines) {
  302. TiffInstance->BadFaxLines = BadFaxLines;
  303. }
  304. BadFaxLines = 1;
  305. LastLineBad = TRUE;
  306. }
  307. } else {
  308. LastLineBad = FALSE;
  309. }
  310. if (!TiffInstance->StartGood) {
  311. TiffInstance->StartGood = i - 1;
  312. }
  313. //
  314. // set the decoding tree
  315. //
  316. OneDimensional = (octet & 0x80) == 0x80;
  317. Tree = OneDimensional ? WhiteDecodeTree : TwoDecodeTree;
  318. //
  319. // reset the control variables
  320. //
  321. TiffInstance->Color = 0;
  322. code = 0;
  323. a0 = 0;
  324. a1 = 0;
  325. b1 = 0;
  326. b2 = 0;
  327. //
  328. // if there is a non-zero runlength then
  329. // spaw the reference & current line pointers
  330. // and count this line. the runlength can be
  331. // zero when there is just an empty eol in
  332. // the stream.
  333. //
  334. if (SingleLineBuffer) {
  335. TiffInstance->bitbuf = OutputBuffer;
  336. }
  337. if (TiffInstance->RunLength) {
  338. TiffInstance->RunLength = 0;
  339. Lines += 1;
  340. prefline = pcurrline;
  341. pcurrline = TiffInstance->bitbuf;
  342. } else {
  343. //
  344. // the eol count is maintained to that
  345. // an rtc sequence is detected.
  346. //
  347. EolCount += 1;
  348. if (EolCount == 6) {
  349. //
  350. // this is an rtc sequence, so any
  351. // data that follows in the file
  352. // is garbage.
  353. //
  354. goto good_exit;
  355. }
  356. }
  357. continue;
  358. }
  359. if (code == DECODEEOL) {
  360. if (!(octet&0x80)) {
  361. //
  362. // here we skip all bits until we hit a 1 bit
  363. // this happens when the first octet in a line
  364. // is all zeroes and we detect that we are
  365. // searching for an EOL
  366. //
  367. continue;
  368. }
  369. //
  370. // this forces the code to pickup the next
  371. // bit in the stream, which tells whether
  372. // the next line is encoded in MH or MR compression
  373. //
  374. code = DECODEEOL2;
  375. continue;
  376. }
  377. if (code == BADRUN) {
  378. code = 0;
  379. continue;
  380. }
  381. code = ((octet&0x80)>>7) ? Tree[code].Right : Tree[code].Left;
  382. b1 = NextChangingElement( prefline, a0, lineWidth, !TiffInstance->Color );
  383. b1 = NextChangingElement( prefline, b1, lineWidth, TiffInstance->Color );
  384. b2 = NextChangingElement( prefline, b1, lineWidth, GetBit(prefline, b1 ) );
  385. if (OneDimensional) {
  386. if (code < 1) {
  387. code = (-code);
  388. OutputCodeBits( TiffInstance, code );
  389. //
  390. // the affect of this is to accumulate the runlengths
  391. // into a0, causing a0 to be placed on a2 when horizontal
  392. // mode is completed/
  393. //
  394. a0 += code;
  395. if (code < 64) {
  396. //
  397. // terminating code
  398. //
  399. TiffInstance->Color = !TiffInstance->Color;
  400. Tree = TiffInstance->Color ? BlackDecodeTree : WhiteDecodeTree;
  401. if (HorzRuns) {
  402. HorzRuns -= 1;
  403. if (!HorzRuns) {
  404. Tree = TwoDecodeTree;
  405. OneDimensional = FALSE;
  406. }
  407. }
  408. }
  409. code = 0;
  410. }
  411. continue;
  412. }
  413. if (code == HORZMODE) {
  414. //
  415. // horizontal mode occurs when b1-a1 greater than 3
  416. //
  417. code= 0;
  418. HorzRuns = 2;
  419. OneDimensional = TRUE;
  420. Tree = TiffInstance->Color ? BlackDecodeTree : WhiteDecodeTree;
  421. } else if (code == PASSMODE) {
  422. //
  423. // pass mode occurs when the position of b2 lies
  424. // to the left of a1, but a1 cannot be equal to b2.
  425. //
  426. code = b2 - a0;
  427. OutputCodeBits( TiffInstance, code );
  428. code = 0;
  429. a0 = b2;
  430. } else if (code >= VTMODE3N && code <= VTMODE3P) {
  431. //
  432. // vertical mode occurs when b1-a1 <= 3
  433. //
  434. a1 = b1 - (VTMODE0 - code);
  435. code = a1 - a0;
  436. OutputCodeBits( TiffInstance, code );
  437. code = 0;
  438. a0 = a1;
  439. TiffInstance->Color = !TiffInstance->Color;
  440. }
  441. }
  442. }
  443. good_exit:
  444. TiffInstance->EndGood = i;
  445. if (BadFaxLines > TiffInstance->BadFaxLines) {
  446. TiffInstance->BadFaxLines = BadFaxLines;
  447. }
  448. FlushBits( TiffInstance );
  449. TiffInstance->Lines = Lines;
  450. return TRUE;
  451. }
  452. BOOL
  453. DecodeMMRFaxData(
  454. PTIFF_INSTANCE_DATA TiffInstance,
  455. LPBYTE OutputBuffer,
  456. BOOL SingleLineBuffer,
  457. DWORD PadLength
  458. )
  459. /*++
  460. Routine Description:
  461. Decode a single page of 2 dimensionaly compressed
  462. TIFF data.
  463. Arguments:
  464. TiffInstance - Pointer to the TIFF instance data
  465. OutputBuffer - Output buffer where the uncompressed data
  466. is written. This buffer must be allocated
  467. by the caller and must be large enough for
  468. a single page of data.
  469. Return Value:
  470. NONE
  471. --*/
  472. {
  473. DWORD i;
  474. DWORD j;
  475. BYTE octet;
  476. PDECODE_TREE Tree;
  477. INT code;
  478. LPBYTE prefline;
  479. LPBYTE pcurrline;
  480. DWORD HorzRuns;
  481. BOOL OneDimensional;
  482. DWORD a0;
  483. DWORD a1;
  484. DWORD b1;
  485. DWORD b2;
  486. PBYTE plinebuf;
  487. DWORD lineWidth;
  488. DWORD Lines;
  489. DWORD EolCount;
  490. //
  491. // initialization
  492. //
  493. if (!SingleLineBuffer) {
  494. __try {
  495. FillMemory( OutputBuffer, TiffInstance->ImageHeight * (TiffInstance->ImageWidth / 8), WHITE );
  496. } __except (EXCEPTION_EXECUTE_HANDLER) {
  497. return FALSE;
  498. }
  499. }
  500. Tree = TwoDecodeTree;
  501. code = 0;
  502. HorzRuns = 0;
  503. EolCount = 0;
  504. TiffInstance->Color = 0;
  505. TiffInstance->RunLength = 0;
  506. TiffInstance->bitdata = 0;
  507. TiffInstance->bitcnt = DWORDBITS;
  508. TiffInstance->bitbuf = OutputBuffer;
  509. OneDimensional = FALSE;
  510. plinebuf = TiffInstance->StripData;
  511. lineWidth = TiffInstance->ImageWidth;
  512. pcurrline = OutputBuffer;
  513. prefline = OutputBuffer;
  514. a0 = 0;
  515. a1 = 0;
  516. b1 = 0;
  517. b2 = 0;
  518. Lines = 0;
  519. //
  520. // loop thru each byte in the file
  521. //
  522. for (j=0; j<TiffInstance->StripDataSize; j++) {
  523. octet = *plinebuf++;
  524. //
  525. // loop thru each bit in the byte
  526. //
  527. for (i=0; i<8; i++,octet<<=1) {
  528. if (Lines + 1 == TiffInstance->ImageHeight && TiffInstance->RunLength == lineWidth)
  529. {
  530. goto good_exit;
  531. }
  532. //
  533. // if the OneDimensional flag is set and the RunLength == lineWidth
  534. // then it means that the last run length was horizontal mode
  535. // and it was not a terminating code. in this case we must go
  536. // process the remaining termination code before ending the line.
  537. //
  538. // if the OneDimensional flag is NOT set and the RunLength == lineWidth
  539. // then we are at the end of a line. for mmr compression there are
  540. // no eols, so this is the pseudo eol.
  541. //
  542. if ((TiffInstance->RunLength == lineWidth) && (!OneDimensional)) {
  543. //
  544. // set the decoding tree
  545. //
  546. Tree = TwoDecodeTree;
  547. //
  548. // reset the control variables
  549. //
  550. TiffInstance->Color = 0;
  551. code = 0;
  552. a0 = 0;
  553. a1 = 0;
  554. b1 = 0;
  555. b2 = 0;
  556. Tree = TwoDecodeTree;
  557. OneDimensional = FALSE;
  558. //
  559. // if there is a non-zero runlength then
  560. // spaw the reference & current line pointers
  561. // and count this line. the runlength can be
  562. // zero when there is just an empty eol in
  563. // the stream.
  564. //
  565. if (SingleLineBuffer) {
  566. TiffInstance->bitbuf = OutputBuffer;
  567. }
  568. TiffInstance->RunLength = 0;
  569. Lines += 1;
  570. prefline = pcurrline;
  571. pcurrline = TiffInstance->bitbuf;
  572. b1 = GetBit(prefline, 0) ? 0 : NextChangingElement(prefline, 0, lineWidth, 0);
  573. } else if (code == DECODEEOL2) {
  574. //
  575. // the eol count is maintained to that
  576. // an rtc sequence is detected.
  577. //
  578. EolCount += 1;
  579. if (EolCount == 2) {
  580. //
  581. // this is an rtc sequence, so any
  582. // data that follows in the file
  583. // is garbage.
  584. //
  585. goto good_exit;
  586. }
  587. continue;
  588. } else if (code == DECODEEOL) {
  589. if (!(octet&0x80)) {
  590. //
  591. // here we skip all bits until we hit a 1 bit
  592. // this happens when the first octet in a line
  593. // is all zeroes and we detect that we are
  594. // searching for an EOL
  595. //
  596. continue;
  597. }
  598. //
  599. // this forces the code to pickup the next
  600. // bit in the stream, which tells whether
  601. // the next line is encoded in MH or MR compression
  602. //
  603. code = DECODEEOL2;
  604. continue;
  605. } else if (code == BADRUN) {
  606. code = 0;
  607. continue;
  608. } else {
  609. b1 = NextChangingElement( prefline, a0, lineWidth, !TiffInstance->Color );
  610. b1 = NextChangingElement( prefline, b1, lineWidth, TiffInstance->Color );
  611. }
  612. b2 = NextChangingElement( prefline, b1, lineWidth, GetBit(prefline, b1 ) );
  613. code = ((octet&0x80)>>7) ? Tree[code].Right : Tree[code].Left;
  614. if (OneDimensional) {
  615. if (code < 1) {
  616. code = (-code);
  617. OutputCodeBits( TiffInstance, code );
  618. //
  619. // the affect of this is to accumulate the runlengths
  620. // into a0, causing a0 to be placed on a2 when horizontal
  621. // mode is completed/
  622. //
  623. a0 += code;
  624. if (code < 64) {
  625. //
  626. // terminating code
  627. //
  628. TiffInstance->Color = !TiffInstance->Color;
  629. Tree = TiffInstance->Color ? BlackDecodeTree : WhiteDecodeTree;
  630. if (HorzRuns) {
  631. HorzRuns -= 1;
  632. if (!HorzRuns) {
  633. Tree = TwoDecodeTree;
  634. OneDimensional = FALSE;
  635. }
  636. }
  637. }
  638. code = 0;
  639. }
  640. continue;
  641. }
  642. if (code == HORZMODE) {
  643. //
  644. // horizontal mode occurs when b1-a1 greater than 3
  645. //
  646. code= 0;
  647. HorzRuns = 2;
  648. OneDimensional = TRUE;
  649. Tree = TiffInstance->Color ? BlackDecodeTree : WhiteDecodeTree;
  650. } else if (code == PASSMODE) {
  651. //
  652. // pass mode occurs when the position of b2 lies
  653. // to the left of a1, but a1 cannot be equal to b2.
  654. //
  655. code = b2 - a0;
  656. OutputCodeBits( TiffInstance, code );
  657. code = 0;
  658. a0 = b2;
  659. } else if (code >= VTMODE3N && code <= VTMODE3P) {
  660. //
  661. // vertical mode occurs when b1-a1 <= 3
  662. //
  663. a1 = b1 - (VTMODE0 - code);
  664. code = a1 - a0;
  665. OutputCodeBits( TiffInstance, code );
  666. code = 0;
  667. a0 = a1;
  668. TiffInstance->Color = !TiffInstance->Color;
  669. }
  670. }
  671. }
  672. good_exit:
  673. FlushBits( TiffInstance );
  674. TiffInstance->Lines = Lines;
  675. return TRUE;
  676. }