00001
00002
00003
00004
00005
00006
00007
00008
00009 #include <string.h>
00010 #include "antiword.h"
00011
00012
00013 #define MAX_FILESIZE 0x2000000UL
00014
00015
00016
00017
00018 static int
00019 iGet2InfoLength(int iByteNbr, const UCHAR *aucGrpprl)
00020 {
00021 int iTmp, iDel, iAdd;
00022
00023 switch (ucGetByte(iByteNbr, aucGrpprl)) {
00024 case 3: case 15: case 78: case 152: case 154: case 155:
00025 return 2 + (int)ucGetByte(iByteNbr + 1, aucGrpprl);
00026 case 16: case 17: case 18: case 19: case 21: case 22: case 26:
00027 case 27: case 28: case 30: case 31: case 32: case 33: case 34:
00028 case 35: case 36: case 38: case 39: case 40: case 41: case 42:
00029 case 43: case 45: case 46: case 47: case 48: case 49: case 68:
00030 case 71: case 72: case 82: case 83: case 96: case 97: case 98:
00031 case 99: case 115: case 116: case 119: case 120: case 123: case 124:
00032 case 129: case 130: case 131: case 132: case 135: case 136: case 139:
00033 case 140: case 141: case 142: case 143: case 144: case 145: case 146:
00034 case 147: case 148: case 153: case 159: case 161: case 162:
00035 return 1 + 2;
00036 case 23:
00037 iTmp = (int)ucGetByte(iByteNbr + 1, aucGrpprl);
00038 if (iTmp == 255) {
00039 iDel = (int)ucGetByte(iByteNbr + 2, aucGrpprl);
00040 iAdd = (int)ucGetByte(
00041 iByteNbr + 3 + iDel * 4, aucGrpprl);
00042 iTmp = 2 + iDel * 4 + iAdd * 3;
00043 }
00044 return 2 + iTmp;
00045 case 70:
00046 return 1 + 3;
00047 case 95:
00048 return 1 + 13;
00049 case 157: case 163:
00050 return 1 + 5;
00051 case 158: case 160: case 164:
00052 return 1 + 4;
00053 default:
00054 return 1 + 1;
00055 }
00056 }
00057
00058
00059
00060
00061 void
00062 vGet2DopInfo(FILE *pFile, const UCHAR *aucHeader)
00063 {
00064 document_block_type tDocument;
00065 UCHAR *aucBuffer;
00066 ULONG ulBeginDocpInfo, ulTmp;
00067 size_t tDocpInfoLen;
00068 USHORT usTmp;
00069
00070 ulBeginDocpInfo = ulGetLong(0x112, aucHeader);
00071 DBG_HEX(ulBeginDocpInfo);
00072 tDocpInfoLen = (size_t)usGetWord(0x116, aucHeader);
00073 DBG_DEC(tDocpInfoLen);
00074 if (tDocpInfoLen < 28) {
00075 DBG_MSG("No Document information");
00076 return;
00077 }
00078
00079 aucBuffer = xmalloc(tDocpInfoLen);
00080 if (!bReadBytes(aucBuffer, tDocpInfoLen, ulBeginDocpInfo, pFile)) {
00081 aucBuffer = xfree(aucBuffer);
00082 return;
00083 }
00084
00085 usTmp = usGetWord(0x00, aucBuffer);
00086 tDocument.ucHdrFtrSpecification = (UCHAR)(usTmp >> 8);
00087 tDocument.usDefaultTabWidth = usGetWord(0x0a, aucBuffer);
00088 ulTmp = ulGetLong(0x14, aucBuffer);
00089 tDocument.tCreateDate = tConvertDTTM(ulTmp);
00090 ulTmp = ulGetLong(0x18, aucBuffer);
00091 tDocument.tRevisedDate = tConvertDTTM(ulTmp);
00092 vCreateDocumentInfoList(&tDocument);
00093
00094 aucBuffer = xfree(aucBuffer);
00095 }
00096
00097
00098
00099
00100
00101 static void
00102 vGet2SectionInfo(const UCHAR *aucGrpprl, size_t tBytes,
00103 section_block_type *pSection)
00104 {
00105 int iFodoOff, iInfoLen;
00106 USHORT usCcol;
00107 UCHAR ucTmp;
00108
00109 fail(aucGrpprl == NULL || pSection == NULL);
00110
00111 iFodoOff = 0;
00112 while (tBytes >= (size_t)iFodoOff + 1) {
00113 switch (ucGetByte(iFodoOff, aucGrpprl)) {
00114 case 117:
00115 ucTmp = ucGetByte(iFodoOff + 1, aucGrpprl);
00116 DBG_DEC(ucTmp);
00117 pSection->bNewPage = ucTmp != 0 && ucTmp != 1;
00118 break;
00119 case 119:
00120 usCcol = 1 + usGetWord(iFodoOff + 1, aucGrpprl);
00121 DBG_DEC(usCcol);
00122 break;
00123 case 128:
00124 pSection->ucHdrFtrSpecification =
00125 ucGetByte(iFodoOff + 1, aucGrpprl);
00126 break;
00127 default:
00128 break;
00129 }
00130 iInfoLen = iGet2InfoLength(iFodoOff, aucGrpprl);
00131 fail(iInfoLen <= 0);
00132 iFodoOff += iInfoLen;
00133 }
00134 }
00135
00136
00137
00138
00139 void
00140 vGet2SepInfo(FILE *pFile, const UCHAR *aucHeader)
00141 {
00142 section_block_type tSection;
00143 ULONG *aulSectPage, *aulCharPos;
00144 UCHAR *aucBuffer, *aucFpage;
00145 ULONG ulBeginOfText, ulTextOffset, ulBeginSectInfo;
00146 size_t tSectInfoLen, tIndex, tOffset, tLen, tBytes;
00147 UCHAR aucTmp[1];
00148
00149 fail(pFile == NULL || aucHeader == NULL);
00150
00151 ulBeginOfText = ulGetLong(0x18, aucHeader);
00152 NO_DBG_HEX(ulBeginOfText);
00153 ulBeginSectInfo = ulGetLong(0x7c, aucHeader);
00154 DBG_HEX(ulBeginSectInfo);
00155 tSectInfoLen = (size_t)usGetWord(0x80, aucHeader);
00156 DBG_DEC(tSectInfoLen);
00157 if (tSectInfoLen < 4) {
00158 DBG_DEC(tSectInfoLen);
00159 return;
00160 }
00161
00162 aucBuffer = xmalloc(tSectInfoLen);
00163 if (!bReadBytes(aucBuffer, tSectInfoLen, ulBeginSectInfo, pFile)) {
00164 aucBuffer = xfree(aucBuffer);
00165 return;
00166 }
00167 NO_DBG_PRINT_BLOCK(aucBuffer, tSectInfoLen);
00168
00169
00170 tLen = (tSectInfoLen - 4) / 10;
00171
00172 aulCharPos = xcalloc(tLen, sizeof(ULONG));
00173 for (tIndex = 0, tOffset = 0;
00174 tIndex < tLen;
00175 tIndex++, tOffset += 4) {
00176 ulTextOffset = ulGetLong(tOffset, aucBuffer);
00177 NO_DBG_HEX(ulTextOffset);
00178 aulCharPos[tIndex] = ulBeginOfText + ulTextOffset;
00179 NO_DBG_HEX(aulCharPos[tIndex]);
00180 }
00181
00182 aulSectPage = xcalloc(tLen, sizeof(ULONG));
00183 for (tIndex = 0, tOffset = (tLen + 1) * 4;
00184 tIndex < tLen;
00185 tIndex++, tOffset += 6) {
00186 aulSectPage[tIndex] = ulGetLong(tOffset + 2, aucBuffer);
00187 NO_DBG_HEX(aulSectPage[tIndex]);
00188 }
00189 aucBuffer = xfree(aucBuffer);
00190
00191
00192 for (tIndex = 0; tIndex < tLen; tIndex++) {
00193 if (aulSectPage[tIndex] == FC_INVALID) {
00194 vDefault2SectionInfoList(aulCharPos[tIndex]);
00195 continue;
00196 }
00197
00198 if (!bReadBytes(aucTmp, 1, aulSectPage[tIndex], pFile)) {
00199 continue;
00200 }
00201 tBytes = 1 + (size_t)ucGetByte(0, aucTmp);
00202 NO_DBG_DEC(tBytes);
00203
00204 aucFpage = xmalloc(tBytes);
00205 if (!bReadBytes(aucFpage, tBytes, aulSectPage[tIndex], pFile)) {
00206 aucFpage = xfree(aucFpage);
00207 continue;
00208 }
00209 NO_DBG_PRINT_BLOCK(aucFpage, tBytes);
00210
00211 vGetDefaultSection(&tSection);
00212 vGet2SectionInfo(aucFpage + 1, tBytes - 1, &tSection);
00213 vAdd2SectionInfoList(&tSection, aulCharPos[tIndex]);
00214 aucFpage = xfree(aucFpage);
00215 }
00216 aulCharPos = xfree(aulCharPos);
00217 aulSectPage = xfree(aulSectPage);
00218 }
00219
00220
00221
00222
00223 void
00224 vGet2HdrFtrInfo(FILE *pFile, const UCHAR *aucHeader)
00225 {
00226 ULONG *aulCharPos;
00227 UCHAR *aucBuffer;
00228 ULONG ulHdrFtrOffset, ulBeginHdrFtrInfo;
00229 size_t tHdrFtrInfoLen, tIndex, tOffset, tLen;
00230
00231 fail(pFile == NULL || aucHeader == NULL);
00232
00233 ulBeginHdrFtrInfo = ulGetLong(0x9a, aucHeader);
00234 NO_DBG_HEX(ulBeginHdrFtrInfo);
00235 tHdrFtrInfoLen = (size_t)usGetWord(0x9e, aucHeader);
00236 NO_DBG_DEC(tHdrFtrInfoLen);
00237 if (tHdrFtrInfoLen < 8) {
00238 DBG_DEC_C(tHdrFtrInfoLen != 0, tHdrFtrInfoLen);
00239 return;
00240 }
00241
00242 aucBuffer = xmalloc(tHdrFtrInfoLen);
00243 if (!bReadBytes(aucBuffer, tHdrFtrInfoLen, ulBeginHdrFtrInfo, pFile)) {
00244 aucBuffer = xfree(aucBuffer);
00245 return;
00246 }
00247 NO_DBG_PRINT_BLOCK(aucBuffer, tHdrFtrInfoLen);
00248
00249 tLen = tHdrFtrInfoLen / 4 - 1;
00250
00251 aulCharPos = xcalloc(tLen, sizeof(ULONG));
00252 for (tIndex = 0, tOffset = 0;
00253 tIndex < tLen;
00254 tIndex++, tOffset += 4) {
00255 ulHdrFtrOffset = ulGetLong(tOffset, aucBuffer);
00256 NO_DBG_HEX(ulHdrFtrOffset);
00257 aulCharPos[tIndex] = ulHdrFtrOffset2CharPos(ulHdrFtrOffset);
00258 NO_DBG_HEX(aulCharPos[tIndex]);
00259 }
00260 vCreat2HdrFtrInfoList(aulCharPos, tLen);
00261 aulCharPos = xfree(aulCharPos);
00262 aucBuffer = xfree(aucBuffer);
00263 }
00264
00265
00266
00267
00268 row_info_enum
00269 eGet2RowInfo(int iFodo,
00270 const UCHAR *aucGrpprl, int iBytes, row_block_type *pRow)
00271 {
00272 int iFodoOff, iInfoLen;
00273 int iIndex, iSize, iCol;
00274 int iPosCurr, iPosPrev;
00275 USHORT usTmp;
00276 BOOL bFound24_0, bFound24_1, bFound25_0, bFound25_1, bFound154;
00277
00278 fail(iFodo < 0 || aucGrpprl == NULL || pRow == NULL);
00279
00280 iFodoOff = 0;
00281 bFound24_0 = FALSE;
00282 bFound24_1 = FALSE;
00283 bFound25_0 = FALSE;
00284 bFound25_1 = FALSE;
00285 bFound154 = FALSE;
00286 while (iBytes >= iFodoOff + 1) {
00287 iInfoLen = 0;
00288 switch (ucGetByte(iFodo + iFodoOff, aucGrpprl)) {
00289 case 24:
00290 if (odd(ucGetByte(iFodo + iFodoOff + 1, aucGrpprl))) {
00291 bFound24_1 = TRUE;
00292 } else {
00293 bFound24_0 = TRUE;
00294 }
00295 break;
00296 case 25:
00297 if (odd(ucGetByte(iFodo + iFodoOff + 1, aucGrpprl))) {
00298 bFound25_1 = TRUE;
00299 } else {
00300 bFound25_0 = TRUE;
00301 }
00302 break;
00303 case 30:
00304 usTmp = usGetWord(iFodo + iFodoOff + 1, aucGrpprl);
00305 usTmp &= 0x01ff;
00306 NO_DBG_DEC(usTmp >> 6);
00307 if (usTmp == 0) {
00308 pRow->ucBorderInfo &= ~TABLE_BORDER_TOP;
00309 } else {
00310 pRow->ucBorderInfo |= TABLE_BORDER_TOP;
00311 }
00312 break;
00313 case 31:
00314 usTmp = usGetWord(iFodo + iFodoOff + 1, aucGrpprl);
00315 usTmp &= 0x01ff;
00316 NO_DBG_DEC(usTmp >> 6);
00317 if (usTmp == 0) {
00318 pRow->ucBorderInfo &= ~TABLE_BORDER_LEFT;
00319 } else {
00320 pRow->ucBorderInfo |= TABLE_BORDER_LEFT;
00321 }
00322 break;
00323 case 32:
00324 usTmp = usGetWord(iFodo + iFodoOff + 1, aucGrpprl);
00325 usTmp &= 0x01ff;
00326 NO_DBG_DEC(usTmp >> 6);
00327 if (usTmp == 0) {
00328 pRow->ucBorderInfo &= ~TABLE_BORDER_BOTTOM;
00329 } else {
00330 pRow->ucBorderInfo |= TABLE_BORDER_BOTTOM;
00331 }
00332 break;
00333 case 33:
00334 usTmp = usGetWord(iFodo + iFodoOff + 1, aucGrpprl);
00335 usTmp &= 0x01ff;
00336 NO_DBG_DEC(usTmp >> 6);
00337 if (usTmp == 0) {
00338 pRow->ucBorderInfo &= ~TABLE_BORDER_RIGHT;
00339 } else {
00340 pRow->ucBorderInfo |= TABLE_BORDER_RIGHT;
00341 }
00342 break;
00343 case 38:
00344 usTmp = usGetWord(iFodo + iFodoOff + 1, aucGrpprl);
00345 usTmp &= 0x0018;
00346 NO_DBG_DEC(usTmp >> 3);
00347 if (usTmp == 0) {
00348 pRow->ucBorderInfo &= ~TABLE_BORDER_TOP;
00349 } else {
00350 pRow->ucBorderInfo |= TABLE_BORDER_TOP;
00351 }
00352 break;
00353 case 39:
00354 usTmp = usGetWord(iFodo + iFodoOff + 1, aucGrpprl);
00355 usTmp &= 0x0018;
00356 NO_DBG_DEC(usTmp >> 3);
00357 if (usTmp == 0) {
00358 pRow->ucBorderInfo &= ~TABLE_BORDER_LEFT;
00359 } else {
00360 pRow->ucBorderInfo |= TABLE_BORDER_LEFT;
00361 }
00362 break;
00363 case 40:
00364 usTmp = usGetWord(iFodo + iFodoOff + 1, aucGrpprl);
00365 usTmp &= 0x0018;
00366 NO_DBG_DEC(usTmp >> 3);
00367 if (usTmp == 0) {
00368 pRow->ucBorderInfo &= ~TABLE_BORDER_BOTTOM;
00369 } else {
00370 pRow->ucBorderInfo |= TABLE_BORDER_BOTTOM;
00371 }
00372 break;
00373 case 41:
00374 usTmp = usGetWord(iFodo + iFodoOff + 1, aucGrpprl);
00375 usTmp &= 0x0018;
00376 NO_DBG_DEC(usTmp >> 3);
00377 if (usTmp == 0) {
00378 pRow->ucBorderInfo &= ~TABLE_BORDER_RIGHT;
00379 } else {
00380 pRow->ucBorderInfo |= TABLE_BORDER_RIGHT;
00381 }
00382 break;
00383 case 152:
00384 case 154:
00385 iSize = (int)usGetWord(iFodo + iFodoOff + 1, aucGrpprl);
00386 if (iSize < 6 || iBytes < iFodoOff + 7) {
00387 DBG_DEC(iSize);
00388 DBG_DEC(iBytes);
00389 DBG_DEC(iFodoOff);
00390 iInfoLen = 1;
00391 break;
00392 }
00393 iCol = (int)ucGetByte(iFodo + iFodoOff + 3, aucGrpprl);
00394 if (iCol < 1 ||
00395 iBytes < iFodoOff + 3 + (iCol + 1) * 2) {
00396 DBG_DEC(iCol);
00397 DBG_DEC(iBytes);
00398 DBG_DEC(iFodoOff);
00399 DBG_DEC(ucGetByte(iFodo + iFodoOff, aucGrpprl));
00400 iInfoLen = 1;
00401 break;
00402 }
00403 if (iCol >= (int)elementsof(pRow->asColumnWidth)) {
00404 DBG_DEC(iCol);
00405 werr(1, "The number of columns is corrupt");
00406 }
00407 pRow->ucNumberOfColumns = (UCHAR)iCol;
00408 iPosPrev = (int)(short)usGetWord(
00409 iFodo + iFodoOff + 4,
00410 aucGrpprl);
00411 for (iIndex = 0; iIndex < iCol; iIndex++) {
00412 iPosCurr = (int)(short)usGetWord(
00413 iFodo + iFodoOff + 6 + iIndex * 2,
00414 aucGrpprl);
00415 pRow->asColumnWidth[iIndex] =
00416 (short)(iPosCurr - iPosPrev);
00417 iPosPrev = iPosCurr;
00418 }
00419 bFound154 = TRUE;
00420 break;
00421 default:
00422 break;
00423 }
00424 if (iInfoLen <= 0) {
00425 iInfoLen =
00426 iGet2InfoLength(iFodo + iFodoOff, aucGrpprl);
00427 fail(iInfoLen <= 0);
00428 }
00429 iFodoOff += iInfoLen;
00430 }
00431 if (bFound24_1 && bFound25_1 && bFound154) {
00432 return found_end_of_row;
00433 }
00434 if (bFound24_0 && bFound25_0 && !bFound154) {
00435 return found_not_end_of_row;
00436 }
00437 if (bFound24_1) {
00438 return found_a_cell;
00439 }
00440 if (bFound24_0) {
00441 return found_not_a_cell;
00442 }
00443 return found_nothing;
00444 }
00445
00446
00447
00448
00449
00450 void
00451 vGet2StyleInfo(int iFodo,
00452 const UCHAR *aucGrpprl, int iBytes, style_block_type *pStyle)
00453 {
00454 int iFodoOff, iInfoLen;
00455 int iTmp, iDel, iAdd;
00456 short sTmp;
00457 UCHAR ucTmp;
00458
00459 fail(iFodo < 0 || aucGrpprl == NULL || pStyle == NULL);
00460
00461 NO_DBG_DEC(pStyle->usIstd);
00462
00463 iFodoOff = 0;
00464 while (iBytes >= iFodoOff + 1) {
00465 iInfoLen = 0;
00466 switch (ucGetByte(iFodo + iFodoOff, aucGrpprl)) {
00467 case 2:
00468 sTmp = (short)ucGetByte(
00469 iFodo + iFodoOff + 1, aucGrpprl);
00470 NO_DBG_DEC(sTmp);
00471 break;
00472 case 5:
00473 pStyle->ucAlignment = ucGetByte(
00474 iFodo + iFodoOff + 1, aucGrpprl);
00475 break;
00476 case 12:
00477 pStyle->ucNFC = ucGetByte(
00478 iFodo + iFodoOff + 1, aucGrpprl);
00479 break;
00480 case 13:
00481 ucTmp = ucGetByte(iFodo + iFodoOff + 1, aucGrpprl);
00482 pStyle->ucNumLevel = ucTmp;
00483 pStyle->bNumPause =
00484 eGetNumType(ucTmp) == level_type_pause;
00485 break;
00486 case 15:
00487 case 23:
00488 iTmp = (int)ucGetByte(iFodo + iFodoOff + 1, aucGrpprl);
00489 if (iTmp < 2) {
00490 iInfoLen = 1;
00491 break;
00492 }
00493 NO_DBG_DEC(iTmp);
00494 iDel = (int)ucGetByte(iFodo + iFodoOff + 2, aucGrpprl);
00495 if (iTmp < 2 + 2 * iDel) {
00496 iInfoLen = 1;
00497 break;
00498 }
00499 NO_DBG_DEC(iDel);
00500 iAdd = (int)ucGetByte(
00501 iFodo + iFodoOff + 3 + 2 * iDel, aucGrpprl);
00502 if (iTmp < 2 + 2 * iDel + 2 * iAdd) {
00503 iInfoLen = 1;
00504 break;
00505 }
00506 NO_DBG_DEC(iAdd);
00507 break;
00508 case 16:
00509 pStyle->sRightIndent = (short)usGetWord(
00510 iFodo + iFodoOff + 1, aucGrpprl);
00511 NO_DBG_DEC(pStyle->sRightIndent);
00512 break;
00513 case 17:
00514 pStyle->sLeftIndent = (short)usGetWord(
00515 iFodo + iFodoOff + 1, aucGrpprl);
00516 NO_DBG_DEC(pStyle->sLeftIndent);
00517 break;
00518 case 18:
00519 sTmp = (short)usGetWord(
00520 iFodo + iFodoOff + 1, aucGrpprl);
00521 pStyle->sLeftIndent += sTmp;
00522 if (pStyle->sLeftIndent < 0) {
00523 pStyle->sLeftIndent = 0;
00524 }
00525 NO_DBG_DEC(sTmp);
00526 NO_DBG_DEC(pStyle->sLeftIndent);
00527 break;
00528 case 19:
00529 pStyle->sLeftIndent1 = (short)usGetWord(
00530 iFodo + iFodoOff + 1, aucGrpprl);
00531 NO_DBG_DEC(pStyle->sLeftIndent1);
00532 break;
00533 case 21:
00534 pStyle->usBeforeIndent = usGetWord(
00535 iFodo + iFodoOff + 1, aucGrpprl);
00536 NO_DBG_DEC(pStyle->usBeforeIndent);
00537 break;
00538 case 22:
00539 pStyle->usAfterIndent = usGetWord(
00540 iFodo + iFodoOff + 1, aucGrpprl);
00541 NO_DBG_DEC(pStyle->usAfterIndent);
00542 break;
00543 default:
00544 break;
00545 }
00546 if (iInfoLen <= 0) {
00547 iInfoLen =
00548 iGet2InfoLength(iFodo + iFodoOff, aucGrpprl);
00549 fail(iInfoLen <= 0);
00550 }
00551 iFodoOff += iInfoLen;
00552 }
00553 }
00554
00555
00556
00557
00558 void
00559 vGet2PapInfo(FILE *pFile, const UCHAR *aucHeader)
00560 {
00561 row_block_type tRow;
00562 style_block_type tStyle;
00563 USHORT *ausParfPage;
00564 UCHAR *aucBuffer;
00565 ULONG ulCharPos, ulCharPosFirst, ulCharPosLast;
00566 ULONG ulBeginParfInfo;
00567 size_t tParfInfoLen, tParfPageNum, tOffset, tSize, tLenOld, tLen;
00568 int iIndex, iIndex2, iRun, iFodo, iLen;
00569 row_info_enum eRowInfo;
00570 USHORT usParfFirstPage, usCount, usIstd;
00571 UCHAR ucStc;
00572 UCHAR aucFpage[BIG_BLOCK_SIZE];
00573
00574 fail(pFile == NULL || aucHeader == NULL);
00575
00576 ulBeginParfInfo = ulGetLong(0xa6, aucHeader);
00577 NO_DBG_HEX(ulBeginParfInfo);
00578 tParfInfoLen = (size_t)usGetWord(0xaa, aucHeader);
00579 NO_DBG_DEC(tParfInfoLen);
00580 if (tParfInfoLen < 4) {
00581 DBG_DEC(tParfInfoLen);
00582 return;
00583 }
00584
00585 aucBuffer = xmalloc(tParfInfoLen);
00586 if (!bReadBytes(aucBuffer, tParfInfoLen, ulBeginParfInfo, pFile)) {
00587 aucBuffer = xfree(aucBuffer);
00588 return;
00589 }
00590 NO_DBG_PRINT_BLOCK(aucBuffer, tParfInfoLen);
00591
00592 tLen = (tParfInfoLen - 4) / 6;
00593 ausParfPage = xcalloc(tLen, sizeof(USHORT));
00594 for (iIndex = 0, tOffset = (tLen + 1) * 4;
00595 iIndex < (int)tLen;
00596 iIndex++, tOffset += 2) {
00597 ausParfPage[iIndex] = usGetWord(tOffset, aucBuffer);
00598 NO_DBG_DEC(ausParfPage[iIndex]);
00599 }
00600 DBG_HEX(ulGetLong(0, aucBuffer));
00601 aucBuffer = xfree(aucBuffer);
00602 tParfPageNum = (size_t)usGetWord(0x144, aucHeader);
00603 DBG_DEC(tParfPageNum);
00604 if (tLen < tParfPageNum) {
00605
00606 tLenOld = tLen;
00607 usParfFirstPage = usGetWord(0x140, aucHeader);
00608 DBG_DEC(usParfFirstPage);
00609 tLen += tParfPageNum - 1;
00610 tSize = tLen * sizeof(USHORT);
00611 ausParfPage = xrealloc(ausParfPage, tSize);
00612
00613 usCount = usParfFirstPage + 1;
00614 for (iIndex = (int)tLenOld; iIndex < (int)tLen; iIndex++) {
00615 ausParfPage[iIndex] = usCount;
00616 NO_DBG_DEC(ausParfPage[iIndex]);
00617 usCount++;
00618 }
00619 }
00620
00621 (void)memset(&tRow, 0, sizeof(tRow));
00622 ulCharPosFirst = CP_INVALID;
00623 for (iIndex = 0; iIndex < (int)tLen; iIndex++) {
00624 if (!bReadBytes(aucFpage, BIG_BLOCK_SIZE,
00625 (ULONG)ausParfPage[iIndex] * BIG_BLOCK_SIZE,
00626 pFile)) {
00627 break;
00628 }
00629 NO_DBG_PRINT_BLOCK(aucFpage, BIG_BLOCK_SIZE);
00630 iRun = (int)ucGetByte(0x1ff, aucFpage);
00631 NO_DBG_DEC(iRun);
00632 for (iIndex2 = 0; iIndex2 < iRun; iIndex2++) {
00633 if ((iRun + 1) * 4 + iIndex2 * 1 >= BIG_BLOCK_SIZE) {
00634 break;
00635 }
00636 NO_DBG_HEX(ulGetLong(iIndex2 * 4, aucFpage));
00637 iFodo = 2 * (int)ucGetByte(
00638 (iRun + 1) * 4 + iIndex2 * 1, aucFpage);
00639 if (iFodo <= 0) {
00640 continue;
00641 }
00642
00643 iLen = 2 * (int)ucGetByte(iFodo, aucFpage);
00644
00645 ucStc = ucGetByte(iFodo + 1, aucFpage);
00646 usIstd = usStc2istd(ucStc);
00647
00648 vFillStyleFromStylesheet(usIstd, &tStyle);
00649 vGet2StyleInfo(iFodo, aucFpage + 8, iLen - 8, &tStyle);
00650 ulCharPos = ulGetLong(iIndex2 * 4, aucFpage);
00651 NO_DBG_HEX(ulCharPos);
00652 tStyle.ulFileOffset = ulCharPos;
00653 vAdd2StyleInfoList(&tStyle);
00654
00655 eRowInfo = eGet2RowInfo(iFodo,
00656 aucFpage + 8, iLen - 8, &tRow);
00657
00658 switch(eRowInfo) {
00659 case found_a_cell:
00660 if (ulCharPosFirst != CP_INVALID) {
00661 break;
00662 }
00663 ulCharPosFirst = ulGetLong(
00664 iIndex2 * 4, aucFpage);
00665 NO_DBG_HEX(ulCharPosFirst);
00666 tRow.ulCharPosStart = ulCharPosFirst;
00667 tRow.ulFileOffsetStart = ulCharPosFirst;
00668 break;
00669 case found_end_of_row:
00670 ulCharPosLast = ulGetLong(
00671 iIndex2 * 4, aucFpage);
00672 NO_DBG_HEX(ulCharPosLast);
00673 tRow.ulCharPosEnd = ulCharPosLast;
00674
00675 tRow.ulFileOffsetEnd = ulCharPosLast + 1;
00676 vAdd2RowInfoList(&tRow);
00677 (void)memset(&tRow, 0, sizeof(tRow));
00678 ulCharPosFirst = CP_INVALID;
00679 break;
00680 case found_nothing:
00681 break;
00682 default:
00683 DBG_DEC(eRowInfo);
00684 break;
00685 }
00686 }
00687 }
00688 ausParfPage = xfree(ausParfPage);
00689 }
00690
00691
00692
00693
00694
00695 void
00696 vGet1FontInfo(int iFodo,
00697 const UCHAR *aucGrpprl, size_t tBytes, font_block_type *pFont)
00698 {
00699 BOOL bIcoChange, bFtcChange, bHpsChange, bKulChange;
00700 USHORT usTmp;
00701 UCHAR ucTmp;
00702 UCHAR aucChpx[12];
00703
00704 fail(iFodo < 0 || aucGrpprl == NULL || pFont == NULL);
00705
00706 if (tBytes > sizeof(aucChpx)) {
00707 NO_DBG_PRINT_BLOCK(aucGrpprl + iFodo, tBytes);
00708 return;
00709 }
00710
00711
00712 (void)memset(aucChpx, 0, sizeof(aucChpx));
00713 (void)memcpy(aucChpx, aucGrpprl + iFodo, min(tBytes, sizeof(aucChpx)));
00714
00715 usTmp = usGetWord(0, aucChpx);
00716 if ((usTmp & BIT(0)) != 0) {
00717 pFont->usFontStyle ^= FONT_BOLD;
00718 }
00719 if ((usTmp & BIT(1)) != 0) {
00720 pFont->usFontStyle ^= FONT_ITALIC;
00721 }
00722 if ((usTmp & BIT(2)) != 0) {
00723 pFont->usFontStyle ^= FONT_STRIKE;
00724 }
00725 if ((usTmp & BIT(5)) != 0) {
00726 pFont->usFontStyle ^= FONT_SMALL_CAPITALS;
00727 }
00728 if ((usTmp & BIT(6)) != 0) {
00729 pFont->usFontStyle ^= FONT_CAPITALS;
00730 }
00731 if ((usTmp & BIT(7)) != 0) {
00732 pFont->usFontStyle ^= FONT_HIDDEN;
00733 }
00734
00735 ucTmp = ucGetByte(5, aucChpx);
00736 if (ucTmp != 0) {
00737 if (ucTmp < 128) {
00738 pFont->usFontStyle |= FONT_SUPERSCRIPT;
00739 DBG_MSG("Superscript");
00740 } else {
00741 pFont->usFontStyle |= FONT_SUBSCRIPT;
00742 DBG_MSG("Subscript");
00743 }
00744 }
00745
00746 bIcoChange = (usTmp & BIT(10)) != 0;
00747 bFtcChange = (usTmp & BIT(11)) != 0;
00748 bHpsChange = (usTmp & BIT(12)) != 0;
00749 bKulChange = (usTmp & BIT(13)) != 0;
00750
00751 if (bFtcChange) {
00752 usTmp = usGetWord(2, aucChpx);
00753 if (usTmp <= (USHORT)UCHAR_MAX) {
00754 pFont->ucFontNumber = (UCHAR)usTmp;
00755 } else {
00756 pFont->ucFontNumber = 0;
00757 }
00758 }
00759
00760 if (bHpsChange) {
00761 pFont->usFontSize = (USHORT)ucGetByte(4, aucChpx);
00762 }
00763
00764 if (bIcoChange || bKulChange) {
00765 usTmp = usGetWord(6, aucChpx);
00766 if (bIcoChange) {
00767 pFont->ucFontColor = (UCHAR)((usTmp & 0x0f00) >> 8);
00768 if (pFont->ucFontColor <= 7) {
00769
00770 pFont->ucFontColor++;
00771 } else {
00772 DBG_DEC(pFont->ucFontColor);
00773 pFont->ucFontColor = 0;
00774 }
00775 }
00776 if (bKulChange) {
00777 usTmp = (usTmp & 0x7000) >> 12;
00778 DBG_DEC_C(usTmp > 4, usTmp);
00779 if (usTmp == 0) {
00780 pFont->usFontStyle &= ~FONT_UNDERLINE;
00781 } else {
00782 pFont->usFontStyle |= FONT_UNDERLINE;
00783 }
00784 }
00785 }
00786 }
00787
00788
00789
00790
00791
00792 void
00793 vGet2FontInfo(int iFodo,
00794 const UCHAR *aucGrpprl, size_t tBytes, font_block_type *pFont)
00795 {
00796 BOOL bIcoChange, bFtcChange, bHpsChange, bKulChange;
00797 USHORT usTmp;
00798 UCHAR ucTmp;
00799 UCHAR aucChpx[18];
00800
00801 fail(iFodo < 0 || aucGrpprl == NULL || pFont == NULL);
00802
00803 if (tBytes > sizeof(aucChpx)) {
00804 NO_DBG_PRINT_BLOCK(aucGrpprl + iFodo, tBytes);
00805 return;
00806 }
00807
00808
00809 (void)memset(aucChpx, 0, sizeof(aucChpx));
00810 (void)memcpy(aucChpx, aucGrpprl + iFodo, min(tBytes, sizeof(aucChpx)));
00811
00812 usTmp = usGetWord(0, aucChpx);
00813 if ((usTmp & BIT(0)) != 0) {
00814 pFont->usFontStyle ^= FONT_BOLD;
00815 }
00816 if ((usTmp & BIT(1)) != 0) {
00817 pFont->usFontStyle ^= FONT_ITALIC;
00818 }
00819 if (usTmp & BIT(3)) {
00820 pFont->usFontStyle ^= FONT_MARKDEL;
00821 }
00822 if ((usTmp & BIT(5)) != 0) {
00823 pFont->usFontStyle ^= FONT_SMALL_CAPITALS;
00824 }
00825 if ((usTmp & BIT(6)) != 0) {
00826 pFont->usFontStyle ^= FONT_CAPITALS;
00827 }
00828 if ((usTmp & BIT(7)) != 0) {
00829 pFont->usFontStyle ^= FONT_HIDDEN;
00830 }
00831 if (usTmp & BIT(10)) {
00832 pFont->usFontStyle ^= FONT_STRIKE;
00833 }
00834
00835 ucTmp = ucGetByte(10, aucChpx);
00836 DBG_MSG_C(ucTmp != 0 && ucTmp < 128, "Superscript");
00837 DBG_MSG_C(ucTmp >= 128, "Subscript");
00838
00839 usTmp = usGetWord(2, aucChpx);
00840 if (usTmp == 0) {
00841
00842 return;
00843 }
00844
00845 bIcoChange = (usTmp & BIT(0)) != 0;
00846 bFtcChange = (usTmp & BIT(1)) != 0;
00847 bHpsChange = (usTmp & BIT(2)) != 0;
00848 bKulChange = (usTmp & BIT(3)) != 0;
00849
00850 if (bFtcChange) {
00851 usTmp = usGetWord(4, aucChpx);
00852 if (usTmp <= (USHORT)UCHAR_MAX) {
00853 pFont->ucFontNumber = (UCHAR)usTmp;
00854 } else {
00855 pFont->ucFontNumber = 0;
00856 }
00857 }
00858
00859 if (bHpsChange) {
00860 pFont->usFontSize = usGetWord(6, aucChpx);
00861 }
00862
00863 if (bIcoChange || bKulChange) {
00864 ucTmp = ucGetByte(9, aucChpx);
00865 if (bIcoChange) {
00866 pFont->ucFontColor = ucTmp & 0x1f;
00867 if (pFont->ucFontColor > 16) {
00868 DBG_DEC(pFont->ucFontColor);
00869 pFont->ucFontColor = 0;
00870 }
00871 }
00872 if (bKulChange) {
00873 ucTmp = (ucTmp & 0xe0) >> 5;
00874 DBG_DEC_C(ucTmp > 4, ucTmp);
00875 if (ucTmp == 0) {
00876 pFont->usFontStyle &= ~FONT_UNDERLINE;
00877 } else {
00878 pFont->usFontStyle |= FONT_UNDERLINE;
00879 }
00880 }
00881 }
00882 }
00883
00884
00885
00886
00887
00888 static BOOL
00889 bGet1PicInfo(int iFodo,
00890 const UCHAR *aucGrpprl, size_t tBytes, picture_block_type *pPicture)
00891 {
00892 ULONG ulTmp;
00893 UCHAR aucChpx[12];
00894
00895 fail(iFodo < 0 || aucGrpprl == NULL || pPicture == NULL);
00896
00897 if (tBytes > sizeof(aucChpx)) {
00898 NO_DBG_PRINT_BLOCK(aucGrpprl + iFodo, tBytes);
00899 tBytes = sizeof(aucChpx);
00900 }
00901
00902
00903 (void)memset(aucChpx, 0, sizeof(aucChpx));
00904 (void)memcpy(aucChpx, aucGrpprl + iFodo, min(tBytes, sizeof(aucChpx)));
00905
00906 ulTmp = ulGetLong(8, aucChpx);
00907 if (ulTmp != 0 && ulTmp < MAX_FILESIZE) {
00908 pPicture->ulPictureOffset = ulTmp;
00909 DBG_HEX(pPicture->ulPictureOffset);
00910 return TRUE;
00911 }
00912 return FALSE;
00913 }
00914
00915
00916
00917
00918
00919 static BOOL
00920 bGet2PicInfo(int iFodo,
00921 const UCHAR *aucGrpprl, size_t tBytes, picture_block_type *pPicture)
00922 {
00923 ULONG ulTmp;
00924 UCHAR aucChpx[18];
00925
00926 fail(iFodo < 0 || aucGrpprl == NULL || pPicture == NULL);
00927
00928 if (tBytes > sizeof(aucChpx)) {
00929 NO_DBG_PRINT_BLOCK(aucGrpprl + iFodo, tBytes);
00930 tBytes = sizeof(aucChpx);
00931 }
00932
00933
00934 (void)memset(aucChpx, 0, sizeof(aucChpx));
00935 (void)memcpy(aucChpx, aucGrpprl + iFodo, min(tBytes, sizeof(aucChpx)));
00936
00937 ulTmp = ulGetLong(14, aucChpx);
00938 if (ulTmp != 0 && ulTmp < MAX_FILESIZE) {
00939 pPicture->ulPictureOffset = ulTmp;
00940 DBG_HEX(pPicture->ulPictureOffset);
00941 DBG_DEC(tBytes);
00942 return TRUE;
00943 }
00944 return FALSE;
00945 }
00946
00947
00948
00949
00950 void
00951 vGet2ChrInfo(FILE *pFile, int iWordVersion, const UCHAR *aucHeader)
00952 {
00953 font_block_type tFont;
00954 picture_block_type tPicture;
00955 USHORT *ausCharPage;
00956 UCHAR *aucBuffer;
00957 ULONG ulFileOffset, ulCharPos, ulBeginCharInfo;
00958 size_t tCharInfoLen, tOffset, tSize, tChrLen, tCharPageNum;
00959 size_t tLenOld, tLen;
00960 int iIndex, iIndex2, iRun, iFodo;
00961 BOOL bSuccess1, bSuccess2;
00962 USHORT usCharFirstPage, usCount, usIstd;
00963 UCHAR aucFpage[BIG_BLOCK_SIZE];
00964
00965 fail(pFile == NULL || aucHeader == NULL);
00966 fail(iWordVersion != 1 && iWordVersion != 2);
00967
00968 ulBeginCharInfo = ulGetLong(0xa0, aucHeader);
00969 DBG_HEX(ulBeginCharInfo);
00970 tCharInfoLen = (size_t)usGetWord(0xa4, aucHeader);
00971 DBG_DEC(tCharInfoLen);
00972 if (tCharInfoLen < 4) {
00973 DBG_DEC(tCharInfoLen);
00974 return;
00975 }
00976
00977 aucBuffer = xmalloc(tCharInfoLen);
00978 if (!bReadBytes(aucBuffer, tCharInfoLen, ulBeginCharInfo, pFile)) {
00979 aucBuffer = xfree(aucBuffer);
00980 return;
00981 }
00982 NO_DBG_PRINT_BLOCK(aucBuffer, tCharInfoLen);
00983
00984 tLen = (tCharInfoLen - 4) / 6;
00985 ausCharPage = xcalloc(tLen, sizeof(USHORT));
00986 for (iIndex = 0, tOffset = (tLen + 1) * 4;
00987 iIndex < (int)tLen;
00988 iIndex++, tOffset += 2) {
00989 ausCharPage[iIndex] = usGetWord(tOffset, aucBuffer);
00990 NO_DBG_DEC(ausCharPage[iIndex]);
00991 }
00992 DBG_HEX(ulGetLong(0, aucBuffer));
00993 aucBuffer = xfree(aucBuffer);
00994 tCharPageNum = (size_t)usGetWord(0x142, aucHeader);
00995 DBG_DEC(tCharPageNum);
00996 if (tLen < tCharPageNum) {
00997
00998 tLenOld = tLen;
00999 usCharFirstPage = usGetWord(0x13e, aucHeader);
01000 NO_DBG_DEC(usCharFirstPage);
01001 tLen += tCharPageNum - 1;
01002 tSize = tLen * sizeof(USHORT);
01003 ausCharPage = xrealloc(ausCharPage, tSize);
01004
01005 usCount = usCharFirstPage + 1;
01006 for (iIndex = (int)tLenOld; iIndex < (int)tLen; iIndex++) {
01007 ausCharPage[iIndex] = usCount;
01008 NO_DBG_DEC(ausCharPage[iIndex]);
01009 usCount++;
01010 }
01011 }
01012
01013 for (iIndex = 0; iIndex < (int)tLen; iIndex++) {
01014 if (!bReadBytes(aucFpage, BIG_BLOCK_SIZE,
01015 (ULONG)ausCharPage[iIndex] * BIG_BLOCK_SIZE,
01016 pFile)) {
01017 break;
01018 }
01019 NO_DBG_PRINT_BLOCK(aucFpage, BIG_BLOCK_SIZE);
01020 iRun = (int)ucGetByte(0x1ff, aucFpage);
01021 NO_DBG_DEC(iRun);
01022 for (iIndex2 = 0; iIndex2 < iRun; iIndex2++) {
01023 if ((iRun + 1) * 4 + iIndex2 >= BIG_BLOCK_SIZE) {
01024 break;
01025 }
01026 ulCharPos = ulGetLong(iIndex2 * 4, aucFpage);
01027 ulFileOffset = ulCharPos;
01028 iFodo = 2 * (int)ucGetByte(
01029 (iRun + 1) * 4 + iIndex2, aucFpage);
01030
01031 tChrLen = (size_t)ucGetByte(iFodo, aucFpage);
01032
01033 usIstd = usGetIstd(ulFileOffset);
01034 vFillFontFromStylesheet(usIstd, &tFont);
01035 if (iFodo != 0) {
01036 if (iWordVersion == 1) {
01037 vGet1FontInfo(iFodo,
01038 aucFpage + 1, tChrLen, &tFont);
01039 } else if (iWordVersion == 2) {
01040 vGet2FontInfo(iFodo,
01041 aucFpage + 1, tChrLen, &tFont);
01042 }
01043 }
01044 tFont.ulFileOffset = ulFileOffset;
01045 vAdd2FontInfoList(&tFont);
01046
01047 if (iFodo <= 0) {
01048 continue;
01049 }
01050
01051 (void)memset(&tPicture, 0, sizeof(tPicture));
01052 bSuccess1 = iWordVersion == 1 &&
01053 bGet1PicInfo(iFodo, aucFpage + 1,
01054 tChrLen, &tPicture);
01055 bSuccess2 = iWordVersion == 2 &&
01056 bGet2PicInfo(iFodo, aucFpage + 1,
01057 tChrLen, &tPicture);
01058 if (bSuccess1 || bSuccess2) {
01059 tPicture.ulFileOffset = ulFileOffset;
01060 tPicture.ulFileOffsetPicture =
01061 tPicture.ulPictureOffset;
01062 vAdd2PictInfoList(&tPicture);
01063 }
01064 }
01065 }
01066 ausCharPage = xfree(ausCharPage);
01067 }