dib2eps.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509
  1. /*
  2. * dib2eps.c
  3. * Copyright (C) 2000-2003 A.J. van Os; Released under GPL
  4. *
  5. * Description:
  6. * Functions to translate dib pictures into eps
  7. *
  8. *================================================================
  9. * This part of the software is based on:
  10. * The Windows Bitmap Decoder Class part of paintlib
  11. * Paintlib is copyright (c) 1996-2000 Ulrich von Zadow
  12. *================================================================
  13. * The credit should go to him, but all the bugs are mine.
  14. */
  15. #include <stdio.h>
  16. #include "antiword.h"
  17. /*
  18. * vDecode1bpp - decode an uncompressed 1 bit per pixel image
  19. */
  20. static void
  21. vDecode1bpp(FILE *pInFile, FILE *pOutFile, const imagedata_type *pImg)
  22. {
  23. size_t tPadding;
  24. int iX, iY, iN, iByte, iTmp, iEighthWidth, iUse;
  25. DBG_MSG("vDecode1bpp");
  26. fail(pOutFile == NULL);
  27. fail(pImg == NULL);
  28. fail(pImg->iColorsUsed < 1 || pImg->iColorsUsed > 2);
  29. DBG_DEC(pImg->iWidth);
  30. DBG_DEC(pImg->iHeight);
  31. iEighthWidth = (pImg->iWidth + 7) / 8;
  32. tPadding = (size_t)(ROUND4(iEighthWidth) - iEighthWidth);
  33. for (iY = 0; iY < pImg->iHeight; iY++) {
  34. for (iX = 0; iX < iEighthWidth; iX++) {
  35. iByte = iNextByte(pInFile);
  36. if (iByte == EOF) {
  37. vASCII85EncodeByte(pOutFile, EOF);
  38. return;
  39. }
  40. if (iX == iEighthWidth - 1 && pImg->iWidth % 8 != 0) {
  41. iUse = pImg->iWidth % 8;
  42. } else {
  43. iUse = 8;
  44. }
  45. for (iN = 0; iN < iUse; iN++) {
  46. switch (iN) {
  47. case 0: iTmp = (iByte & 0x80) / 128; break;
  48. case 1: iTmp = (iByte & 0x40) / 64; break;
  49. case 2: iTmp = (iByte & 0x20) / 32; break;
  50. case 3: iTmp = (iByte & 0x10) / 16; break;
  51. case 4: iTmp = (iByte & 0x08) / 8; break;
  52. case 5: iTmp = (iByte & 0x04) / 4; break;
  53. case 6: iTmp = (iByte & 0x02) / 2; break;
  54. case 7: iTmp = (iByte & 0x01); break;
  55. default: iTmp = 0; break;
  56. }
  57. vASCII85EncodeByte(pOutFile, iTmp);
  58. }
  59. }
  60. (void)tSkipBytes(pInFile, tPadding);
  61. }
  62. vASCII85EncodeByte(pOutFile, EOF);
  63. } /* end of vDecode1bpp */
  64. /*
  65. * vDecode4bpp - decode an uncompressed 4 bits per pixel image
  66. */
  67. static void
  68. vDecode4bpp(FILE *pInFile, FILE *pOutFile, const imagedata_type *pImg)
  69. {
  70. size_t tPadding;
  71. int iX, iY, iN, iByte, iTmp, iHalfWidth, iUse;
  72. DBG_MSG("vDecode4bpp");
  73. fail(pInFile == NULL);
  74. fail(pOutFile == NULL);
  75. fail(pImg == NULL);
  76. fail(pImg->iColorsUsed < 1 || pImg->iColorsUsed > 16);
  77. DBG_DEC(pImg->iWidth);
  78. DBG_DEC(pImg->iHeight);
  79. iHalfWidth = (pImg->iWidth + 1) / 2;
  80. tPadding = (size_t)(ROUND4(iHalfWidth) - iHalfWidth);
  81. for (iY = 0; iY < pImg->iHeight; iY++) {
  82. for (iX = 0; iX < iHalfWidth; iX++) {
  83. iByte = iNextByte(pInFile);
  84. if (iByte == EOF) {
  85. vASCII85EncodeByte(pOutFile, EOF);
  86. return;
  87. }
  88. if (iX == iHalfWidth - 1 && odd(pImg->iWidth)) {
  89. iUse = 1;
  90. } else {
  91. iUse = 2;
  92. }
  93. for (iN = 0; iN < iUse; iN++) {
  94. if (odd(iN)) {
  95. iTmp = iByte & 0x0f;
  96. } else {
  97. iTmp = (iByte & 0xf0) / 16;
  98. }
  99. vASCII85EncodeByte(pOutFile, iTmp);
  100. }
  101. }
  102. (void)tSkipBytes(pInFile, tPadding);
  103. }
  104. vASCII85EncodeByte(pOutFile, EOF);
  105. } /* end of vDecode4bpp */
  106. /*
  107. * vDecode8bpp - decode an uncompressed 8 bits per pixel image
  108. */
  109. static void
  110. vDecode8bpp(FILE *pInFile, FILE *pOutFile, const imagedata_type *pImg)
  111. {
  112. size_t tPadding;
  113. int iX, iY, iByte;
  114. DBG_MSG("vDecode8bpp");
  115. fail(pInFile == NULL);
  116. fail(pOutFile == NULL);
  117. fail(pImg == NULL);
  118. fail(pImg->iColorsUsed < 1 || pImg->iColorsUsed > 256);
  119. DBG_DEC(pImg->iWidth);
  120. DBG_DEC(pImg->iHeight);
  121. tPadding = (size_t)(ROUND4(pImg->iWidth) - pImg->iWidth);
  122. for (iY = 0; iY < pImg->iHeight; iY++) {
  123. for (iX = 0; iX < pImg->iWidth; iX++) {
  124. iByte = iNextByte(pInFile);
  125. if (iByte == EOF) {
  126. vASCII85EncodeByte(pOutFile, EOF);
  127. return;
  128. }
  129. vASCII85EncodeByte(pOutFile, iByte);
  130. }
  131. (void)tSkipBytes(pInFile, tPadding);
  132. }
  133. vASCII85EncodeByte(pOutFile, EOF);
  134. } /* end of vDecode8bpp */
  135. /*
  136. * vDecode24bpp - decode an uncompressed 24 bits per pixel image
  137. */
  138. static void
  139. vDecode24bpp(FILE *pInFile, FILE *pOutFile, const imagedata_type *pImg)
  140. {
  141. size_t tPadding;
  142. int iX, iY, iBlue, iGreen, iRed, iTripleWidth;
  143. DBG_MSG("vDecode24bpp");
  144. fail(pInFile == NULL);
  145. fail(pOutFile == NULL);
  146. fail(pImg == NULL);
  147. fail(!pImg->bColorImage);
  148. DBG_DEC(pImg->iWidth);
  149. DBG_DEC(pImg->iHeight);
  150. iTripleWidth = pImg->iWidth * 3;
  151. tPadding = (size_t)(ROUND4(iTripleWidth) - iTripleWidth);
  152. for (iY = 0; iY < pImg->iHeight; iY++) {
  153. for (iX = 0; iX < pImg->iWidth; iX++) {
  154. /* Change from BGR order to RGB order */
  155. iBlue = iNextByte(pInFile);
  156. if (iBlue == EOF) {
  157. vASCII85EncodeByte(pOutFile, EOF);
  158. return;
  159. }
  160. iGreen = iNextByte(pInFile);
  161. if (iGreen == EOF) {
  162. vASCII85EncodeByte(pOutFile, EOF);
  163. return;
  164. }
  165. iRed = iNextByte(pInFile);
  166. if (iRed == EOF) {
  167. vASCII85EncodeByte(pOutFile, EOF);
  168. return;
  169. }
  170. vASCII85EncodeByte(pOutFile, iRed);
  171. vASCII85EncodeByte(pOutFile, iGreen);
  172. vASCII85EncodeByte(pOutFile, iBlue);
  173. }
  174. (void)tSkipBytes(pInFile, tPadding);
  175. }
  176. vASCII85EncodeByte(pOutFile, EOF);
  177. } /* end of vDecode24bpp */
  178. /*
  179. * vDecodeRle4 - decode a RLE compressed 4 bits per pixel image
  180. */
  181. static void
  182. vDecodeRle4(FILE *pInFile, FILE *pOutFile, const imagedata_type *pImg)
  183. {
  184. int iX, iY, iByte, iTmp, iRunLength, iRun;
  185. BOOL bEOF, bEOL;
  186. DBG_MSG("vDecodeRle4");
  187. fail(pInFile == NULL);
  188. fail(pOutFile == NULL);
  189. fail(pImg == NULL);
  190. fail(pImg->iColorsUsed < 1 || pImg->iColorsUsed > 16);
  191. DBG_DEC(pImg->iWidth);
  192. DBG_DEC(pImg->iHeight);
  193. bEOF = FALSE;
  194. for (iY = 0; iY < pImg->iHeight && !bEOF; iY++) {
  195. bEOL = FALSE;
  196. iX = 0;
  197. while (!bEOL) {
  198. iRunLength = iNextByte(pInFile);
  199. if (iRunLength == EOF) {
  200. vASCII85EncodeByte(pOutFile, EOF);
  201. return;
  202. }
  203. if (iRunLength != 0) {
  204. /*
  205. * Encoded packet:
  206. * RunLength pixels, all the "same" value
  207. */
  208. iByte = iNextByte(pInFile);
  209. if (iByte == EOF) {
  210. vASCII85EncodeByte(pOutFile, EOF);
  211. return;
  212. }
  213. for (iRun = 0; iRun < iRunLength; iRun++) {
  214. if (odd(iRun)) {
  215. iTmp = iByte & 0x0f;
  216. } else {
  217. iTmp = (iByte & 0xf0) / 16;
  218. }
  219. if (iX < pImg->iWidth) {
  220. vASCII85EncodeByte(pOutFile, iTmp);
  221. }
  222. iX++;
  223. }
  224. continue;
  225. }
  226. /* Literal or escape */
  227. iRunLength = iNextByte(pInFile);
  228. if (iRunLength == EOF) {
  229. vASCII85EncodeByte(pOutFile, EOF);
  230. return;
  231. }
  232. if (iRunLength == 0) { /* End of line escape */
  233. bEOL = TRUE;
  234. } else if (iRunLength == 1) { /* End of file escape */
  235. bEOF = TRUE;
  236. bEOL = TRUE;
  237. } else if (iRunLength == 2) { /* Delta escape */
  238. DBG_MSG("RLE4: encountered delta escape");
  239. bEOF = TRUE;
  240. bEOL = TRUE;
  241. } else { /* Literal packet */
  242. iByte = 0;
  243. for (iRun = 0; iRun < iRunLength; iRun++) {
  244. if (odd(iRun)) {
  245. iTmp = iByte & 0x0f;
  246. } else {
  247. iByte = iNextByte(pInFile);
  248. if (iByte == EOF) {
  249. vASCII85EncodeByte(pOutFile, EOF);
  250. return;
  251. }
  252. iTmp = (iByte & 0xf0) / 16;
  253. }
  254. if (iX < pImg->iWidth) {
  255. vASCII85EncodeByte(pOutFile, iTmp);
  256. }
  257. iX++;
  258. }
  259. /* Padding if the number of bytes is odd */
  260. if (odd((iRunLength + 1) / 2)) {
  261. (void)tSkipBytes(pInFile, 1);
  262. }
  263. }
  264. }
  265. DBG_DEC_C(iX != pImg->iWidth, iX);
  266. }
  267. vASCII85EncodeByte(pOutFile, EOF);
  268. } /* end of vDecodeRle4 */
  269. /*
  270. * vDecodeRle8 - decode a RLE compressed 8 bits per pixel image
  271. */
  272. static void
  273. vDecodeRle8(FILE *pInFile, FILE *pOutFile, const imagedata_type *pImg)
  274. {
  275. int iX, iY, iByte, iRunLength, iRun;
  276. BOOL bEOF, bEOL;
  277. DBG_MSG("vDecodeRle8");
  278. fail(pInFile == NULL);
  279. fail(pOutFile == NULL);
  280. fail(pImg == NULL);
  281. fail(pImg->iColorsUsed < 1 || pImg->iColorsUsed > 256);
  282. DBG_DEC(pImg->iWidth);
  283. DBG_DEC(pImg->iHeight);
  284. bEOF = FALSE;
  285. for (iY = 0; iY < pImg->iHeight && !bEOF; iY++) {
  286. bEOL = FALSE;
  287. iX = 0;
  288. while (!bEOL) {
  289. iRunLength = iNextByte(pInFile);
  290. if (iRunLength == EOF) {
  291. vASCII85EncodeByte(pOutFile, EOF);
  292. return;
  293. }
  294. if (iRunLength != 0) {
  295. /*
  296. * Encoded packet:
  297. * RunLength pixels, all the same value
  298. */
  299. iByte = iNextByte(pInFile);
  300. if (iByte == EOF) {
  301. vASCII85EncodeByte(pOutFile, EOF);
  302. return;
  303. }
  304. for (iRun = 0; iRun < iRunLength; iRun++) {
  305. if (iX < pImg->iWidth) {
  306. vASCII85EncodeByte(pOutFile, iByte);
  307. }
  308. iX++;
  309. }
  310. continue;
  311. }
  312. /* Literal or escape */
  313. iRunLength = iNextByte(pInFile);
  314. if (iRunLength == EOF) {
  315. vASCII85EncodeByte(pOutFile, EOF);
  316. return;
  317. }
  318. if (iRunLength == 0) { /* End of line escape */
  319. bEOL = TRUE;
  320. } else if (iRunLength == 1) { /* End of file escape */
  321. bEOF = TRUE;
  322. bEOL = TRUE;
  323. } else if (iRunLength == 2) { /* Delta escape */
  324. DBG_MSG("RLE8: encountered delta escape");
  325. bEOF = TRUE;
  326. bEOL = TRUE;
  327. } else { /* Literal packet */
  328. for (iRun = 0; iRun < iRunLength; iRun++) {
  329. iByte = iNextByte(pInFile);
  330. if (iByte == EOF) {
  331. vASCII85EncodeByte(pOutFile, EOF);
  332. return;
  333. }
  334. if (iX < pImg->iWidth) {
  335. vASCII85EncodeByte(pOutFile, iByte);
  336. }
  337. iX++;
  338. }
  339. /* Padding if the number of bytes is odd */
  340. if (odd(iRunLength)) {
  341. (void)tSkipBytes(pInFile, 1);
  342. }
  343. }
  344. }
  345. DBG_DEC_C(iX != pImg->iWidth, iX);
  346. }
  347. vASCII85EncodeByte(pOutFile, EOF);
  348. } /* end of vDecodeRle8 */
  349. /*
  350. * vDecodeDIB - decode a dib picture
  351. */
  352. static void
  353. vDecodeDIB(FILE *pInFile, FILE *pOutFile, const imagedata_type *pImg)
  354. {
  355. size_t tHeaderSize;
  356. fail(pInFile == NULL);
  357. fail(pOutFile == NULL);
  358. fail(pImg == NULL);
  359. /* Skip the bitmap info header */
  360. tHeaderSize = (size_t)ulNextLong(pInFile);
  361. (void)tSkipBytes(pInFile, tHeaderSize - 4);
  362. /* Skip the colortable */
  363. if (pImg->uiBitsPerComponent <= 8) {
  364. (void)tSkipBytes(pInFile,
  365. (size_t)(pImg->iColorsUsed *
  366. ((tHeaderSize > 12) ? 4 : 3)));
  367. }
  368. switch (pImg->uiBitsPerComponent) {
  369. case 1:
  370. fail(pImg->eCompression != compression_none);
  371. vDecode1bpp(pInFile, pOutFile, pImg);
  372. break;
  373. case 4:
  374. fail(pImg->eCompression != compression_none &&
  375. pImg->eCompression != compression_rle4);
  376. if (pImg->eCompression == compression_rle4) {
  377. vDecodeRle4(pInFile, pOutFile, pImg);
  378. } else {
  379. vDecode4bpp(pInFile, pOutFile, pImg);
  380. }
  381. break;
  382. case 8:
  383. fail(pImg->eCompression != compression_none &&
  384. pImg->eCompression != compression_rle8);
  385. if (pImg->eCompression == compression_rle8) {
  386. vDecodeRle8(pInFile, pOutFile, pImg);
  387. } else {
  388. vDecode8bpp(pInFile, pOutFile, pImg);
  389. }
  390. break;
  391. case 24:
  392. fail(pImg->eCompression != compression_none);
  393. vDecode24bpp(pInFile, pOutFile, pImg);
  394. break;
  395. default:
  396. DBG_DEC(pImg->uiBitsPerComponent);
  397. break;
  398. }
  399. } /* end of vDecodeDIB */
  400. #if defined(DEBUG)
  401. /*
  402. * vCopy2File
  403. */
  404. static void
  405. vCopy2File(FILE *pInFile, ULONG ulFileOffset, size_t tPictureLen)
  406. {
  407. static int iPicCounter = 0;
  408. FILE *pOutFile;
  409. size_t tIndex;
  410. int iTmp;
  411. char szFilename[30];
  412. if (!bSetDataOffset(pInFile, ulFileOffset)) {
  413. return;
  414. }
  415. sprintf(szFilename, "/tmp/pic/pic%04d.bmp", ++iPicCounter);
  416. pOutFile = fopen(szFilename, "wb");
  417. if (pOutFile == NULL) {
  418. return;
  419. }
  420. /* Turn a dib into a bmp by adding a fake 14 byte header */
  421. (void)putc('B', pOutFile);
  422. (void)putc('M', pOutFile);
  423. for (iTmp = 0; iTmp < 12; iTmp++) {
  424. if (putc(0, pOutFile) == EOF) {
  425. break;
  426. }
  427. }
  428. for (tIndex = 0; tIndex < tPictureLen; tIndex++) {
  429. iTmp = iNextByte(pInFile);
  430. if (putc(iTmp, pOutFile) == EOF) {
  431. break;
  432. }
  433. }
  434. (void)fclose(pOutFile);
  435. } /* end of vCopy2File */
  436. #endif /* DEBUG */
  437. /*
  438. * bTranslateDIB - translate a DIB picture
  439. *
  440. * This function translates a picture from dib to eps
  441. *
  442. * return TRUE when sucessful, otherwise FALSE
  443. */
  444. BOOL
  445. bTranslateDIB(diagram_type *pDiag, FILE *pInFile,
  446. ULONG ulFileOffset, const imagedata_type *pImg)
  447. {
  448. #if defined(DEBUG)
  449. fail(pImg->tPosition > pImg->tLength);
  450. vCopy2File(pInFile, ulFileOffset, pImg->tLength - pImg->tPosition);
  451. #endif /* DEBUG */
  452. /* Seek to start position of DIB data */
  453. if (!bSetDataOffset(pInFile, ulFileOffset)) {
  454. return FALSE;
  455. }
  456. vImagePrologue(pDiag, pImg);
  457. vDecodeDIB(pInFile, pDiag->pOutFile, pImg);
  458. vImageEpilogue(pDiag);
  459. return TRUE;
  460. } /* end of bTranslateDIB */