00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include <stdio.h>
00017 #include "antiword.h"
00018
00019
00020
00021
00022
00023 static void
00024 vDecode1bpp(FILE *pInFile, FILE *pOutFile, const imagedata_type *pImg)
00025 {
00026 size_t tPadding;
00027 int iX, iY, iN, iByte, iTmp, iEighthWidth, iUse;
00028
00029 DBG_MSG("vDecode1bpp");
00030
00031 fail(pOutFile == NULL);
00032 fail(pImg == NULL);
00033 fail(pImg->iColorsUsed < 1 || pImg->iColorsUsed > 2);
00034
00035 DBG_DEC(pImg->iWidth);
00036 DBG_DEC(pImg->iHeight);
00037
00038 iEighthWidth = (pImg->iWidth + 7) / 8;
00039 tPadding = (size_t)(ROUND4(iEighthWidth) - iEighthWidth);
00040
00041 for (iY = 0; iY < pImg->iHeight; iY++) {
00042 for (iX = 0; iX < iEighthWidth; iX++) {
00043 iByte = iNextByte(pInFile);
00044 if (iByte == EOF) {
00045 vASCII85EncodeByte(pOutFile, EOF);
00046 return;
00047 }
00048 if (iX == iEighthWidth - 1 && pImg->iWidth % 8 != 0) {
00049 iUse = pImg->iWidth % 8;
00050 } else {
00051 iUse = 8;
00052 }
00053 for (iN = 0; iN < iUse; iN++) {
00054 switch (iN) {
00055 case 0: iTmp = (iByte & 0x80) / 128; break;
00056 case 1: iTmp = (iByte & 0x40) / 64; break;
00057 case 2: iTmp = (iByte & 0x20) / 32; break;
00058 case 3: iTmp = (iByte & 0x10) / 16; break;
00059 case 4: iTmp = (iByte & 0x08) / 8; break;
00060 case 5: iTmp = (iByte & 0x04) / 4; break;
00061 case 6: iTmp = (iByte & 0x02) / 2; break;
00062 case 7: iTmp = (iByte & 0x01); break;
00063 default: iTmp = 0; break;
00064 }
00065 vASCII85EncodeByte(pOutFile, iTmp);
00066 }
00067 }
00068 (void)tSkipBytes(pInFile, tPadding);
00069 }
00070 vASCII85EncodeByte(pOutFile, EOF);
00071 }
00072
00073
00074
00075
00076 static void
00077 vDecode4bpp(FILE *pInFile, FILE *pOutFile, const imagedata_type *pImg)
00078 {
00079 size_t tPadding;
00080 int iX, iY, iN, iByte, iTmp, iHalfWidth, iUse;
00081
00082 DBG_MSG("vDecode4bpp");
00083
00084 fail(pInFile == NULL);
00085 fail(pOutFile == NULL);
00086 fail(pImg == NULL);
00087 fail(pImg->iColorsUsed < 1 || pImg->iColorsUsed > 16);
00088
00089 DBG_DEC(pImg->iWidth);
00090 DBG_DEC(pImg->iHeight);
00091
00092 iHalfWidth = (pImg->iWidth + 1) / 2;
00093 tPadding = (size_t)(ROUND4(iHalfWidth) - iHalfWidth);
00094
00095 for (iY = 0; iY < pImg->iHeight; iY++) {
00096 for (iX = 0; iX < iHalfWidth; iX++) {
00097 iByte = iNextByte(pInFile);
00098 if (iByte == EOF) {
00099 vASCII85EncodeByte(pOutFile, EOF);
00100 return;
00101 }
00102 if (iX == iHalfWidth - 1 && odd(pImg->iWidth)) {
00103 iUse = 1;
00104 } else {
00105 iUse = 2;
00106 }
00107 for (iN = 0; iN < iUse; iN++) {
00108 if (odd(iN)) {
00109 iTmp = iByte & 0x0f;
00110 } else {
00111 iTmp = (iByte & 0xf0) / 16;
00112 }
00113 vASCII85EncodeByte(pOutFile, iTmp);
00114 }
00115 }
00116 (void)tSkipBytes(pInFile, tPadding);
00117 }
00118 vASCII85EncodeByte(pOutFile, EOF);
00119 }
00120
00121
00122
00123
00124 static void
00125 vDecode8bpp(FILE *pInFile, FILE *pOutFile, const imagedata_type *pImg)
00126 {
00127 size_t tPadding;
00128 int iX, iY, iByte;
00129
00130 DBG_MSG("vDecode8bpp");
00131
00132 fail(pInFile == NULL);
00133 fail(pOutFile == NULL);
00134 fail(pImg == NULL);
00135 fail(pImg->iColorsUsed < 1 || pImg->iColorsUsed > 256);
00136
00137 DBG_DEC(pImg->iWidth);
00138 DBG_DEC(pImg->iHeight);
00139
00140 tPadding = (size_t)(ROUND4(pImg->iWidth) - pImg->iWidth);
00141
00142 for (iY = 0; iY < pImg->iHeight; iY++) {
00143 for (iX = 0; iX < pImg->iWidth; iX++) {
00144 iByte = iNextByte(pInFile);
00145 if (iByte == EOF) {
00146 vASCII85EncodeByte(pOutFile, EOF);
00147 return;
00148 }
00149 vASCII85EncodeByte(pOutFile, iByte);
00150 }
00151 (void)tSkipBytes(pInFile, tPadding);
00152 }
00153 vASCII85EncodeByte(pOutFile, EOF);
00154 }
00155
00156
00157
00158
00159 static void
00160 vDecode24bpp(FILE *pInFile, FILE *pOutFile, const imagedata_type *pImg)
00161 {
00162 size_t tPadding;
00163 int iX, iY, iBlue, iGreen, iRed, iTripleWidth;
00164
00165 DBG_MSG("vDecode24bpp");
00166
00167 fail(pInFile == NULL);
00168 fail(pOutFile == NULL);
00169 fail(pImg == NULL);
00170 fail(!pImg->bColorImage);
00171
00172 DBG_DEC(pImg->iWidth);
00173 DBG_DEC(pImg->iHeight);
00174
00175 iTripleWidth = pImg->iWidth * 3;
00176 tPadding = (size_t)(ROUND4(iTripleWidth) - iTripleWidth);
00177
00178 for (iY = 0; iY < pImg->iHeight; iY++) {
00179 for (iX = 0; iX < pImg->iWidth; iX++) {
00180
00181 iBlue = iNextByte(pInFile);
00182 if (iBlue == EOF) {
00183 vASCII85EncodeByte(pOutFile, EOF);
00184 return;
00185 }
00186 iGreen = iNextByte(pInFile);
00187 if (iGreen == EOF) {
00188 vASCII85EncodeByte(pOutFile, EOF);
00189 return;
00190 }
00191 iRed = iNextByte(pInFile);
00192 if (iRed == EOF) {
00193 vASCII85EncodeByte(pOutFile, EOF);
00194 return;
00195 }
00196 vASCII85EncodeByte(pOutFile, iRed);
00197 vASCII85EncodeByte(pOutFile, iGreen);
00198 vASCII85EncodeByte(pOutFile, iBlue);
00199 }
00200 (void)tSkipBytes(pInFile, tPadding);
00201 }
00202 vASCII85EncodeByte(pOutFile, EOF);
00203 }
00204
00205
00206
00207
00208 static void
00209 vDecodeRle4(FILE *pInFile, FILE *pOutFile, const imagedata_type *pImg)
00210 {
00211 int iX, iY, iByte, iTmp, iRunLength, iRun;
00212 BOOL bEOF, bEOL;
00213
00214 DBG_MSG("vDecodeRle4");
00215
00216 fail(pInFile == NULL);
00217 fail(pOutFile == NULL);
00218 fail(pImg == NULL);
00219 fail(pImg->iColorsUsed < 1 || pImg->iColorsUsed > 16);
00220
00221 DBG_DEC(pImg->iWidth);
00222 DBG_DEC(pImg->iHeight);
00223
00224 bEOF = FALSE;
00225
00226 for (iY = 0; iY < pImg->iHeight && !bEOF; iY++) {
00227 bEOL = FALSE;
00228 iX = 0;
00229 while (!bEOL) {
00230 iRunLength = iNextByte(pInFile);
00231 if (iRunLength == EOF) {
00232 vASCII85EncodeByte(pOutFile, EOF);
00233 return;
00234 }
00235 if (iRunLength != 0) {
00236
00237
00238
00239
00240 iByte = iNextByte(pInFile);
00241 if (iByte == EOF) {
00242 vASCII85EncodeByte(pOutFile, EOF);
00243 return;
00244 }
00245 for (iRun = 0; iRun < iRunLength; iRun++) {
00246 if (odd(iRun)) {
00247 iTmp = iByte & 0x0f;
00248 } else {
00249 iTmp = (iByte & 0xf0) / 16;
00250 }
00251 if (iX < pImg->iWidth) {
00252 vASCII85EncodeByte(pOutFile, iTmp);
00253 }
00254 iX++;
00255 }
00256 continue;
00257 }
00258
00259 iRunLength = iNextByte(pInFile);
00260 if (iRunLength == EOF) {
00261 vASCII85EncodeByte(pOutFile, EOF);
00262 return;
00263 }
00264 if (iRunLength == 0) {
00265 bEOL = TRUE;
00266 } else if (iRunLength == 1) {
00267 bEOF = TRUE;
00268 bEOL = TRUE;
00269 } else if (iRunLength == 2) {
00270 DBG_MSG("RLE4: encountered delta escape");
00271 bEOF = TRUE;
00272 bEOL = TRUE;
00273 } else {
00274 iByte = 0;
00275 for (iRun = 0; iRun < iRunLength; iRun++) {
00276 if (odd(iRun)) {
00277 iTmp = iByte & 0x0f;
00278 } else {
00279 iByte = iNextByte(pInFile);
00280 if (iByte == EOF) {
00281 vASCII85EncodeByte(pOutFile, EOF);
00282 return;
00283 }
00284 iTmp = (iByte & 0xf0) / 16;
00285 }
00286 if (iX < pImg->iWidth) {
00287 vASCII85EncodeByte(pOutFile, iTmp);
00288 }
00289 iX++;
00290 }
00291
00292 if (odd((iRunLength + 1) / 2)) {
00293 (void)tSkipBytes(pInFile, 1);
00294 }
00295 }
00296 }
00297 DBG_DEC_C(iX != pImg->iWidth, iX);
00298 }
00299 vASCII85EncodeByte(pOutFile, EOF);
00300 }
00301
00302
00303
00304
00305 static void
00306 vDecodeRle8(FILE *pInFile, FILE *pOutFile, const imagedata_type *pImg)
00307 {
00308 int iX, iY, iByte, iRunLength, iRun;
00309 BOOL bEOF, bEOL;
00310
00311 DBG_MSG("vDecodeRle8");
00312
00313 fail(pInFile == NULL);
00314 fail(pOutFile == NULL);
00315 fail(pImg == NULL);
00316 fail(pImg->iColorsUsed < 1 || pImg->iColorsUsed > 256);
00317
00318 DBG_DEC(pImg->iWidth);
00319 DBG_DEC(pImg->iHeight);
00320
00321 bEOF = FALSE;
00322
00323 for (iY = 0; iY < pImg->iHeight && !bEOF; iY++) {
00324 bEOL = FALSE;
00325 iX = 0;
00326 while (!bEOL) {
00327 iRunLength = iNextByte(pInFile);
00328 if (iRunLength == EOF) {
00329 vASCII85EncodeByte(pOutFile, EOF);
00330 return;
00331 }
00332 if (iRunLength != 0) {
00333
00334
00335
00336
00337 iByte = iNextByte(pInFile);
00338 if (iByte == EOF) {
00339 vASCII85EncodeByte(pOutFile, EOF);
00340 return;
00341 }
00342 for (iRun = 0; iRun < iRunLength; iRun++) {
00343 if (iX < pImg->iWidth) {
00344 vASCII85EncodeByte(pOutFile, iByte);
00345 }
00346 iX++;
00347 }
00348 continue;
00349 }
00350
00351 iRunLength = iNextByte(pInFile);
00352 if (iRunLength == EOF) {
00353 vASCII85EncodeByte(pOutFile, EOF);
00354 return;
00355 }
00356 if (iRunLength == 0) {
00357 bEOL = TRUE;
00358 } else if (iRunLength == 1) {
00359 bEOF = TRUE;
00360 bEOL = TRUE;
00361 } else if (iRunLength == 2) {
00362 DBG_MSG("RLE8: encountered delta escape");
00363 bEOF = TRUE;
00364 bEOL = TRUE;
00365 } else {
00366 for (iRun = 0; iRun < iRunLength; iRun++) {
00367 iByte = iNextByte(pInFile);
00368 if (iByte == EOF) {
00369 vASCII85EncodeByte(pOutFile, EOF);
00370 return;
00371 }
00372 if (iX < pImg->iWidth) {
00373 vASCII85EncodeByte(pOutFile, iByte);
00374 }
00375 iX++;
00376 }
00377
00378 if (odd(iRunLength)) {
00379 (void)tSkipBytes(pInFile, 1);
00380 }
00381 }
00382 }
00383 DBG_DEC_C(iX != pImg->iWidth, iX);
00384 }
00385 vASCII85EncodeByte(pOutFile, EOF);
00386 }
00387
00388
00389
00390
00391 static void
00392 vDecodeDIB(FILE *pInFile, FILE *pOutFile, const imagedata_type *pImg)
00393 {
00394 size_t tHeaderSize;
00395
00396 fail(pInFile == NULL);
00397 fail(pOutFile == NULL);
00398 fail(pImg == NULL);
00399
00400
00401 tHeaderSize = (size_t)ulNextLong(pInFile);
00402 (void)tSkipBytes(pInFile, tHeaderSize - 4);
00403
00404 if (pImg->uiBitsPerComponent <= 8) {
00405 (void)tSkipBytes(pInFile,
00406 (size_t)(pImg->iColorsUsed *
00407 ((tHeaderSize > 12) ? 4 : 3)));
00408 }
00409
00410 switch (pImg->uiBitsPerComponent) {
00411 case 1:
00412 fail(pImg->eCompression != compression_none);
00413 vDecode1bpp(pInFile, pOutFile, pImg);
00414 break;
00415 case 4:
00416 fail(pImg->eCompression != compression_none &&
00417 pImg->eCompression != compression_rle4);
00418 if (pImg->eCompression == compression_rle4) {
00419 vDecodeRle4(pInFile, pOutFile, pImg);
00420 } else {
00421 vDecode4bpp(pInFile, pOutFile, pImg);
00422 }
00423 break;
00424 case 8:
00425 fail(pImg->eCompression != compression_none &&
00426 pImg->eCompression != compression_rle8);
00427 if (pImg->eCompression == compression_rle8) {
00428 vDecodeRle8(pInFile, pOutFile, pImg);
00429 } else {
00430 vDecode8bpp(pInFile, pOutFile, pImg);
00431 }
00432 break;
00433 case 24:
00434 fail(pImg->eCompression != compression_none);
00435 vDecode24bpp(pInFile, pOutFile, pImg);
00436 break;
00437 default:
00438 DBG_DEC(pImg->uiBitsPerComponent);
00439 break;
00440 }
00441 }
00442
00443 #if defined(DEBUG)
00444
00445
00446
00447 static void
00448 vCopy2File(FILE *pInFile, ULONG ulFileOffset, size_t tPictureLen)
00449 {
00450 static int iPicCounter = 0;
00451 FILE *pOutFile;
00452 size_t tIndex;
00453 int iTmp;
00454 char szFilename[30];
00455
00456 if (!bSetDataOffset(pInFile, ulFileOffset)) {
00457 return;
00458 }
00459
00460 sprintf(szFilename, "/tmp/pic/pic%04d.bmp", ++iPicCounter);
00461 pOutFile = fopen(szFilename, "wb");
00462 if (pOutFile == NULL) {
00463 return;
00464 }
00465
00466 (void)putc('B', pOutFile);
00467 (void)putc('M', pOutFile);
00468 for (iTmp = 0; iTmp < 12; iTmp++) {
00469 if (putc(0, pOutFile) == EOF) {
00470 break;
00471 }
00472 }
00473 for (tIndex = 0; tIndex < tPictureLen; tIndex++) {
00474 iTmp = iNextByte(pInFile);
00475 if (putc(iTmp, pOutFile) == EOF) {
00476 break;
00477 }
00478 }
00479 (void)fclose(pOutFile);
00480 }
00481 #endif
00482
00483
00484
00485
00486
00487
00488
00489
00490 BOOL
00491 bTranslateDIB(diagram_type *pDiag, FILE *pInFile,
00492 ULONG ulFileOffset, const imagedata_type *pImg)
00493 {
00494 #if defined(DEBUG)
00495 fail(pImg->tPosition > pImg->tLength);
00496 vCopy2File(pInFile, ulFileOffset, pImg->tLength - pImg->tPosition);
00497 #endif
00498
00499
00500 if (!bSetDataOffset(pInFile, ulFileOffset)) {
00501 return FALSE;
00502 }
00503
00504 vImagePrologue(pDiag, pImg);
00505 vDecodeDIB(pInFile, pDiag->pOutFile, pImg);
00506 vImageEpilogue(pDiag);
00507
00508 return TRUE;
00509 }