examples/PIPS/antiword/src/prop6.c

00001 /*
00002  * prop6.c
00003  * Copyright (C) 1998-2005 A.J. van Os; Released under GPL
00004  *
00005  * Description:
00006  * Read the property information from a MS Word 6 or 7 file
00007  */
00008 
00009 #include <stdlib.h>
00010 #include <string.h>
00011 #include "antiword.h"
00012 
00013 
00014 /*
00015  * iGet6InfoLength - the length of the information for Word 6/7 files
00016  */
00017 static int
00018 iGet6InfoLength(int iByteNbr, const UCHAR *aucGrpprl)
00019 {
00020         int     iTmp, iDel, iAdd;
00021 
00022         switch (ucGetByte(iByteNbr, aucGrpprl)) {
00023         case   2: case  16: case  17: case  18: case  19: case  21: case  22:
00024         case  26: case  27: case  28: case  30: case  31: case  32: case  33:
00025         case  34: case  35: case  36: case  38: case  39: case  40: case  41:
00026         case  42: case  43: case  45: case  46: case  47: case  48: case  49:
00027         case  69: case  72: case  80: case  93: case  96: case  97: case  99:
00028         case 101: case 105: case 106: case 107: case 109: case 110: case 121:
00029         case 122: case 123: case 124: case 140: case 141: case 144: case 145:
00030         case 148: case 149: case 154: case 155: case 156: case 157: case 160:
00031         case 161: case 164: case 165: case 166: case 167: case 168: case 169:
00032         case 170: case 171: case 182: case 183: case 184: case 189: case 195:
00033         case 197: case 198:
00034                 return 1 + 2;
00035         case   3: case  12: case  15: case  81: case 103: case 108: case 188:
00036         case 190: case 191:
00037                 return 2 + (int)ucGetByte(iByteNbr + 1, aucGrpprl);
00038         case  20: case  70: case  74: case 192: case 194: case 196: case 200:
00039                 return 1 + 4;
00040         case  23:
00041                 iTmp = (int)ucGetByte(iByteNbr + 1, aucGrpprl);
00042                 if (iTmp == 255) {
00043                         iDel = (int)ucGetByte(iByteNbr + 2, aucGrpprl);
00044                         iAdd = (int)ucGetByte(
00045                                         iByteNbr + 3 + iDel * 4, aucGrpprl);
00046                         iTmp = 2 + iDel * 4 + iAdd * 3;
00047                 }
00048                 return 2 + iTmp;
00049         case  68: case 193: case 199:
00050                 return 1 + 5;
00051         case  73: case  95: case 136: case 137:
00052                 return 1 + 3;
00053         case 120: case 187:
00054                 return 1 + 12;
00055         default:
00056                 return 1 + 1;
00057         }
00058 } /* end of iGet6InfoLength */
00059 
00060 /*
00061  * Build the lists with Document Property Information for Word 6/7 files
00062  */
00063 void
00064 vGet6DopInfo(FILE *pFile, ULONG ulStartBlock,
00065         const ULONG *aulBBD, size_t tBBDLen,
00066         const UCHAR *aucHeader)
00067 {
00068         document_block_type     tDocument;
00069         UCHAR   *aucBuffer;
00070         ULONG   ulBeginDocpInfo, ulTmp;
00071         size_t  tDocpInfoLen;
00072         USHORT  usTmp;
00073 
00074         ulBeginDocpInfo = ulGetLong(0x150, aucHeader); /* fcDop */
00075         DBG_HEX(ulBeginDocpInfo);
00076         tDocpInfoLen = (size_t)ulGetLong(0x154, aucHeader); /* lcbDop */
00077         DBG_DEC(tDocpInfoLen);
00078         if (tDocpInfoLen < 28) {
00079                 DBG_MSG("No Document information");
00080                 return;
00081         }
00082 
00083         aucBuffer = xmalloc(tDocpInfoLen);
00084         if (!bReadBuffer(pFile, ulStartBlock,
00085                         aulBBD, tBBDLen, BIG_BLOCK_SIZE,
00086                         aucBuffer, ulBeginDocpInfo, tDocpInfoLen)) {
00087                 aucBuffer = xfree(aucBuffer);
00088                 return;
00089         }
00090 
00091         usTmp = usGetWord(0x00, aucBuffer);
00092         tDocument.ucHdrFtrSpecification = (UCHAR)(usTmp >> 8); /* grpfIhdt */
00093         tDocument.usDefaultTabWidth = usGetWord(0x0a, aucBuffer); /* dxaTab */
00094         ulTmp = ulGetLong(0x14, aucBuffer); /* dttmCreated */
00095         tDocument.tCreateDate = tConvertDTTM(ulTmp);
00096         ulTmp = ulGetLong(0x18, aucBuffer); /* dttmRevised */
00097         tDocument.tRevisedDate = tConvertDTTM(ulTmp);
00098         vCreateDocumentInfoList(&tDocument);
00099 
00100         aucBuffer = xfree(aucBuffer);
00101 } /* end of vGet6DopInfo */
00102 
00103 /*
00104  * Fill the section information block with information
00105  * from a Word 6/7 file.
00106  */
00107 static void
00108 vGet6SectionInfo(const UCHAR *aucGrpprl, size_t tBytes,
00109                 section_block_type *pSection)
00110 {
00111         UINT    uiIndex;
00112         int     iFodoOff, iInfoLen, iSize, iTmp;
00113         USHORT  usCcol;
00114         UCHAR   ucTmp;
00115 
00116         fail(aucGrpprl == NULL || pSection == NULL);
00117 
00118         iFodoOff = 0;
00119         while (tBytes >= (size_t)iFodoOff + 1) {
00120                 iInfoLen = 0;
00121                 switch (ucGetByte(iFodoOff, aucGrpprl)) {
00122                 case 133:       /* olstAnm */
00123                         iSize = (int)ucGetByte(iFodoOff + 1, aucGrpprl);
00124                         DBG_DEC_C(iSize != 212, iSize);
00125                         for (uiIndex = 0, iTmp = iFodoOff + 2;
00126                              uiIndex < 9 && iTmp < iFodoOff + 2 + iSize - 15;
00127                              uiIndex++, iTmp += 16) {
00128                                 pSection->aucNFC[uiIndex] =
00129                                                 ucGetByte(iTmp, aucGrpprl);
00130                                 NO_DBG_DEC(pSection->aucNFC[uiIndex]);
00131                                 ucTmp = ucGetByte(iTmp + 3, aucGrpprl);
00132                                 NO_DBG_HEX(ucTmp);
00133                                 if ((ucTmp & BIT(2)) != 0) {
00134                                         pSection->usNeedPrevLvl |=
00135                                                         (USHORT)BIT(uiIndex);
00136                                 }
00137                                 if ((ucTmp & BIT(3)) != 0) {
00138                                         pSection->usHangingIndent |=
00139                                                         (USHORT)BIT(uiIndex);
00140                                 }
00141                         }
00142                         DBG_HEX(pSection->usNeedPrevLvl);
00143                         DBG_HEX(pSection->usHangingIndent);
00144                         break;
00145                 case 142:       /* bkc */
00146                         ucTmp = ucGetByte(iFodoOff + 1, aucGrpprl);
00147                         DBG_DEC(ucTmp);
00148                         pSection->bNewPage = ucTmp != 0 && ucTmp != 1;
00149                         break;
00150                 case 144:       /* ccolM1 */
00151                         usCcol = 1 + usGetWord(iFodoOff + 1, aucGrpprl);
00152                         DBG_DEC(usCcol);
00153                         break;
00154                 case 153:       /* grpfIhdt */
00155                         pSection->ucHdrFtrSpecification =
00156                                         ucGetByte(iFodoOff + 1, aucGrpprl);
00157                         break;
00158                 default:
00159                         break;
00160                 }
00161                 if (iInfoLen <= 0) {
00162                         iInfoLen = iGet6InfoLength(iFodoOff, aucGrpprl);
00163                         fail(iInfoLen <= 0);
00164                 }
00165                 iFodoOff += iInfoLen;
00166         }
00167 } /* end of vGet6SectionInfo */
00168 
00169 /*
00170  * Build the lists with Section Property Information for Word 6/7 files
00171  */
00172 void
00173 vGet6SepInfo(FILE *pFile, ULONG ulStartBlock,
00174         const ULONG *aulBBD, size_t tBBDLen,
00175         const UCHAR *aucHeader)
00176 {
00177         section_block_type      tSection;
00178         ULONG           *aulSectPage, *aulCharPos;
00179         UCHAR   *aucBuffer, *aucFpage;
00180         ULONG   ulBeginOfText, ulTextOffset, ulBeginSectInfo;
00181         size_t  tSectInfoLen, tIndex, tOffset, tLen, tBytes;
00182         UCHAR   aucTmp[2];
00183 
00184         fail(pFile == NULL || aucHeader == NULL);
00185         fail(ulStartBlock > MAX_BLOCKNUMBER && ulStartBlock != END_OF_CHAIN);
00186         fail(aulBBD == NULL);
00187 
00188         ulBeginOfText = ulGetLong(0x18, aucHeader); /* fcMin */
00189         NO_DBG_HEX(ulBeginOfText);
00190         ulBeginSectInfo = ulGetLong(0x88, aucHeader); /* fcPlcfsed */
00191         DBG_HEX(ulBeginSectInfo);
00192         tSectInfoLen = (size_t)ulGetLong(0x8c, aucHeader); /* lcbPlcfsed */
00193         DBG_DEC(tSectInfoLen);
00194         if (tSectInfoLen < 4) {
00195                 DBG_DEC(tSectInfoLen);
00196                 return;
00197         }
00198 
00199         aucBuffer = xmalloc(tSectInfoLen);
00200         if (!bReadBuffer(pFile, ulStartBlock,
00201                         aulBBD, tBBDLen, BIG_BLOCK_SIZE,
00202                         aucBuffer, ulBeginSectInfo, tSectInfoLen)) {
00203                 aucBuffer = xfree(aucBuffer);
00204                 return;
00205         }
00206         NO_DBG_PRINT_BLOCK(aucBuffer, tSectInfoLen);
00207 
00208         /* Read the Section Descriptors */
00209         tLen = (tSectInfoLen - 4) / 16;
00210         /* Save the section offsets */
00211         aulCharPos = xcalloc(tLen, sizeof(ULONG));
00212         for (tIndex = 0, tOffset = 0; tIndex < tLen; tIndex++, tOffset += 4) {
00213                 ulTextOffset = ulGetLong(tOffset, aucBuffer);
00214                 NO_DBG_HEX(ulTextOffset);
00215                 aulCharPos[tIndex] = ulBeginOfText + ulTextOffset;
00216                 NO_DBG_HEX(aulCharPos[tIndex]);
00217         }
00218         /* Save the Sepx offsets */
00219         aulSectPage = xcalloc(tLen, sizeof(ULONG));
00220         for (tIndex = 0, tOffset = (tLen + 1) * 4;
00221              tIndex < tLen;
00222              tIndex++, tOffset += 12) {
00223                 aulSectPage[tIndex] = ulGetLong(tOffset + 2, aucBuffer);
00224                 NO_DBG_HEX(aulSectPage[tIndex]); /* fcSepx */
00225         }
00226         aucBuffer = xfree(aucBuffer);
00227 
00228         /* Read the Section Properties */
00229         for (tIndex = 0; tIndex < tLen; tIndex++) {
00230                 if (aulSectPage[tIndex] == FC_INVALID) {
00231                         vDefault2SectionInfoList(aulCharPos[tIndex]);
00232                         continue;
00233                 }
00234                 /* Get the number of bytes to read */
00235                 if (!bReadBuffer(pFile, ulStartBlock,
00236                                 aulBBD, tBBDLen, BIG_BLOCK_SIZE,
00237                                 aucTmp, aulSectPage[tIndex], 2)) {
00238                         continue;
00239                 }
00240                 tBytes = 2 + (size_t)usGetWord(0, aucTmp);
00241                 NO_DBG_DEC(tBytes);
00242                 /* Read the bytes */
00243                 aucFpage = xmalloc(tBytes);
00244                 if (!bReadBuffer(pFile, ulStartBlock,
00245                                 aulBBD, tBBDLen, BIG_BLOCK_SIZE,
00246                                 aucFpage, aulSectPage[tIndex], tBytes)) {
00247                         aucFpage = xfree(aucFpage);
00248                         continue;
00249                 }
00250                 NO_DBG_PRINT_BLOCK(aucFpage, tBytes);
00251                 /* Process the bytes */
00252                 vGetDefaultSection(&tSection);
00253                 vGet6SectionInfo(aucFpage + 2, tBytes - 2, &tSection);
00254                 vAdd2SectionInfoList(&tSection, aulCharPos[tIndex]);
00255                 aucFpage = xfree(aucFpage);
00256         }
00257         aulCharPos = xfree(aulCharPos);
00258         aulSectPage = xfree(aulSectPage);
00259 } /* end of vGet6SepInfo */
00260 
00261 /*
00262  * Build the list with Header/Footer Information for Word 6/7 files
00263  */
00264 void
00265 vGet6HdrFtrInfo(FILE *pFile, ULONG ulStartBlock,
00266         const ULONG *aulBBD, size_t tBBDLen,
00267         const UCHAR *aucHeader)
00268 {
00269         ULONG   *aulCharPos;
00270         UCHAR   *aucBuffer;
00271         ULONG   ulHdrFtrOffset, ulBeginHdrFtrInfo;
00272         size_t  tHdrFtrInfoLen, tIndex, tOffset, tLen;
00273 
00274         fail(pFile == NULL || aucHeader == NULL);
00275         fail(ulStartBlock > MAX_BLOCKNUMBER && ulStartBlock != END_OF_CHAIN);
00276         fail(aulBBD == NULL);
00277 
00278         ulBeginHdrFtrInfo = ulGetLong(0xb0, aucHeader); /* fcPlcfhdd */
00279         NO_DBG_HEX(ulBeginHdrFtrInfo);
00280         tHdrFtrInfoLen = (size_t)ulGetLong(0xb4, aucHeader); /* lcbPlcfhdd */
00281         NO_DBG_DEC(tHdrFtrInfoLen);
00282         if (tHdrFtrInfoLen < 8) {
00283                 DBG_DEC_C(tHdrFtrInfoLen != 0, tHdrFtrInfoLen);
00284                 return;
00285         }
00286 
00287         aucBuffer = xmalloc(tHdrFtrInfoLen);
00288         if (!bReadBuffer(pFile, ulStartBlock,
00289                         aulBBD, tBBDLen, BIG_BLOCK_SIZE,
00290                         aucBuffer, ulBeginHdrFtrInfo, tHdrFtrInfoLen)) {
00291                 aucBuffer = xfree(aucBuffer);
00292                 return;
00293         }
00294         NO_DBG_PRINT_BLOCK(aucBuffer, tHdrFtrInfoLen);
00295 
00296         tLen = tHdrFtrInfoLen / 4 - 1;
00297         /* Save the header/footer offsets */
00298         aulCharPos = xcalloc(tLen, sizeof(ULONG));
00299         for (tIndex = 0, tOffset = 0;
00300              tIndex < tLen;
00301              tIndex++, tOffset += 4) {
00302                 ulHdrFtrOffset = ulGetLong(tOffset, aucBuffer);
00303                 NO_DBG_HEX(ulHdrFtrOffset);
00304                 aulCharPos[tIndex] = ulHdrFtrOffset2CharPos(ulHdrFtrOffset);
00305                 NO_DBG_HEX(aulCharPos[tIndex]);
00306         }
00307         vCreat6HdrFtrInfoList(aulCharPos, tLen);
00308         aulCharPos = xfree(aulCharPos);
00309         aucBuffer = xfree(aucBuffer);
00310 } /* end of vGet6HdrFtrInfo */
00311 
00312 /*
00313  * Translate the rowinfo to a member of the row_info enumeration
00314  */
00315 row_info_enum
00316 eGet6RowInfo(int iFodo,
00317         const UCHAR *aucGrpprl, int iBytes, row_block_type *pRow)
00318 {
00319         int     iFodoOff, iInfoLen;
00320         int     iIndex, iSize, iCol;
00321         int     iPosCurr, iPosPrev;
00322         USHORT  usTmp;
00323         BOOL    bFound24_0, bFound24_1, bFound25_0, bFound25_1, bFound190;
00324 
00325         fail(iFodo < 0 || aucGrpprl == NULL || pRow == NULL);
00326 
00327         iFodoOff = 0;
00328         bFound24_0 = FALSE;
00329         bFound24_1 = FALSE;
00330         bFound25_0 = FALSE;
00331         bFound25_1 = FALSE;
00332         bFound190 = FALSE;
00333         while (iBytes >= iFodoOff + 1) {
00334                 iInfoLen = 0;
00335                 switch (ucGetByte(iFodo + iFodoOff, aucGrpprl)) {
00336                 case  24:       /* fInTable */
00337                         if (odd(ucGetByte(iFodo + iFodoOff + 1, aucGrpprl))) {
00338                                 bFound24_1 = TRUE;
00339                         } else {
00340                                 bFound24_0 = TRUE;
00341                         }
00342                         break;
00343                 case  25:       /* fTtp */
00344                         if (odd(ucGetByte(iFodo + iFodoOff + 1, aucGrpprl))) {
00345                                 bFound25_1 = TRUE;
00346                         } else {
00347                                 bFound25_0 = TRUE;
00348                         }
00349                         break;
00350                 case 38:        /* brcTop */
00351                         usTmp = usGetWord(iFodo + iFodoOff + 1, aucGrpprl);
00352                         usTmp &= 0x0018;
00353                         NO_DBG_DEC(usTmp >> 3);
00354                         if (usTmp == 0) {
00355                                 pRow->ucBorderInfo &= ~TABLE_BORDER_TOP;
00356                         } else {
00357                                 pRow->ucBorderInfo |= TABLE_BORDER_TOP;
00358                         }
00359                         break;
00360                 case 39:        /* brcLeft */
00361                         usTmp = usGetWord(iFodo + iFodoOff + 1, aucGrpprl);
00362                         usTmp &= 0x0018;
00363                         NO_DBG_DEC(usTmp >> 3);
00364                         if (usTmp == 0) {
00365                                 pRow->ucBorderInfo &= ~TABLE_BORDER_LEFT;
00366                         } else {
00367                                 pRow->ucBorderInfo |= TABLE_BORDER_LEFT;
00368                         }
00369                         break;
00370                 case 40:        /* brcBottom */
00371                         usTmp = usGetWord(iFodo + iFodoOff + 1, aucGrpprl);
00372                         usTmp &= 0x0018;
00373                         NO_DBG_DEC(usTmp >> 3);
00374                         if (usTmp == 0) {
00375                                 pRow->ucBorderInfo &= ~TABLE_BORDER_BOTTOM;
00376                         } else {
00377                                 pRow->ucBorderInfo |= TABLE_BORDER_BOTTOM;
00378                         }
00379                         break;
00380                 case 41:        /* brcRight */
00381                         usTmp = usGetWord(iFodo + iFodoOff + 1, aucGrpprl);
00382                         usTmp &= 0x0018;
00383                         NO_DBG_DEC(usTmp >> 3);
00384                         if (usTmp == 0) {
00385                                 pRow->ucBorderInfo &= ~TABLE_BORDER_RIGHT;
00386                         } else {
00387                                 pRow->ucBorderInfo |= TABLE_BORDER_RIGHT;
00388                         }
00389                         break;
00390                 case 188:       /* cDefTable10 */
00391                         DBG_MSG("188: sprmTDefTable10");
00392                         iSize = (int)usGetWord(iFodo + iFodoOff + 1, aucGrpprl);
00393                         DBG_DEC(iSize);
00394                         break;
00395                 case 190:       /* cDefTable */
00396                         iSize = (int)usGetWord(iFodo + iFodoOff + 1, aucGrpprl);
00397                         if (iSize < 6 || iBytes < iFodoOff + 7) {
00398                                 DBG_DEC(iSize);
00399                                 DBG_DEC(iFodoOff);
00400                                 iInfoLen = 1;
00401                                 break;
00402                         }
00403                         iCol = (int)ucGetByte(iFodo + iFodoOff + 3, aucGrpprl);
00404                         if (iCol < 1 ||
00405                             iBytes < iFodoOff + 3 + (iCol + 1) * 2) {
00406                                 DBG_DEC(iCol);
00407                                 DBG_DEC(iFodoOff);
00408                                 iInfoLen = 1;
00409                                 break;
00410                         }
00411                         if (iCol >= (int)elementsof(pRow->asColumnWidth)) {
00412                                 DBG_DEC(iCol);
00413                                 werr(1, "The number of columns is corrupt");
00414                         }
00415                         pRow->ucNumberOfColumns = (UCHAR)iCol;
00416                         iPosPrev = (int)(short)usGetWord(
00417                                         iFodo + iFodoOff + 4,
00418                                         aucGrpprl);
00419                         for (iIndex = 0; iIndex < iCol; iIndex++) {
00420                                 iPosCurr = (int)(short)usGetWord(
00421                                         iFodo + iFodoOff + 6 + iIndex * 2,
00422                                         aucGrpprl);
00423                                 pRow->asColumnWidth[iIndex] =
00424                                                 (short)(iPosCurr - iPosPrev);
00425                                 iPosPrev = iPosCurr;
00426                         }
00427                         bFound190 = TRUE;
00428                         break;
00429                 default:
00430                         break;
00431                 }
00432                 if (iInfoLen <= 0) {
00433                         iInfoLen =
00434                                 iGet6InfoLength(iFodo + iFodoOff, aucGrpprl);
00435                         fail(iInfoLen <= 0);
00436                 }
00437                 iFodoOff += iInfoLen;
00438         }
00439 
00440         if (bFound25_1 && bFound190) {
00441                 return found_end_of_row;
00442         }
00443         if (bFound25_0 && !bFound190) {
00444                 return found_not_end_of_row;
00445         }
00446         if (bFound24_1) {
00447                 return found_a_cell;
00448         }
00449         if (bFound24_0) {
00450                 return found_not_a_cell;
00451         }
00452         return found_nothing;
00453 } /* end of eGet6RowInfo */
00454 
00455 /*
00456  * Fill the style information block with information
00457  * from a Word 6/7 file.
00458  */
00459 void
00460 vGet6StyleInfo(int iFodo,
00461         const UCHAR *aucGrpprl, int iBytes, style_block_type *pStyle)
00462 {
00463         int     iFodoOff, iInfoLen;
00464         int     iTmp, iDel, iAdd, iBefore;
00465         short   sTmp;
00466         UCHAR   ucTmp;
00467 
00468         fail(iFodo < 0 || aucGrpprl == NULL || pStyle == NULL);
00469 
00470         NO_DBG_DEC(pStyle->usIstd);
00471 
00472         iFodoOff = 0;
00473         while (iBytes >= iFodoOff + 1) {
00474                 iInfoLen = 0;
00475                 switch (ucGetByte(iFodo + iFodoOff, aucGrpprl)) {
00476                 case   2:       /* istd */
00477                         sTmp = (short)ucGetByte(
00478                                         iFodo + iFodoOff + 1, aucGrpprl);
00479                         NO_DBG_DEC(sTmp);
00480                         break;
00481                 case   5:       /* jc */
00482                         pStyle->ucAlignment = ucGetByte(
00483                                         iFodo + iFodoOff + 1, aucGrpprl);
00484                         break;
00485                 case  12:       /* anld */
00486                         iTmp = (int)ucGetByte(
00487                                         iFodo + iFodoOff + 1, aucGrpprl);
00488                         DBG_DEC_C(iTmp < 52, iTmp);
00489                         if (iTmp >= 1) {
00490                                 pStyle->ucNFC = ucGetByte(
00491                                         iFodo + iFodoOff + 2, aucGrpprl);
00492                         }
00493                         if (pStyle->ucNFC != LIST_BULLETS && iTmp >= 2) {
00494                                 iBefore = (int)ucGetByte(
00495                                         iFodo + iFodoOff + 3, aucGrpprl);
00496                         } else {
00497                                 iBefore = 0;
00498                         }
00499                         if (iTmp >= 12) {
00500                                 pStyle->usStartAt = usGetWord(
00501                                         iFodo + iFodoOff + 12, aucGrpprl);
00502                         }
00503                         if (iTmp >= iBefore + 21) {
00504                                 pStyle->usListChar = (USHORT)ucGetByte(
00505                                         iFodo + iFodoOff + iBefore + 22,
00506                                         aucGrpprl);
00507                                 NO_DBG_HEX(pStyle->usListChar);
00508                         }
00509                         break;
00510                 case  13:       /* nLvlAnm */
00511                         ucTmp = ucGetByte(iFodo + iFodoOff + 1, aucGrpprl);
00512                         pStyle->ucNumLevel = ucTmp;
00513                         pStyle->bNumPause =
00514                                 eGetNumType(ucTmp) == level_type_pause;
00515                         break;
00516                 case  15:       /* ChgTabsPapx */
00517                 case  23:       /* ChgTabs */
00518                         iTmp = (int)ucGetByte(iFodo + iFodoOff + 1, aucGrpprl);
00519                         if (iTmp < 2) {
00520                                 iInfoLen = 1;
00521                                 break;
00522                         }
00523                         NO_DBG_DEC(iTmp);
00524                         iDel = (int)ucGetByte(iFodo + iFodoOff + 2, aucGrpprl);
00525                         if (iTmp < 2 + 2 * iDel) {
00526                                 iInfoLen = 1;
00527                                 break;
00528                         }
00529                         NO_DBG_DEC(iDel);
00530                         iAdd = (int)ucGetByte(
00531                                 iFodo + iFodoOff + 3 + 2 * iDel, aucGrpprl);
00532                         if (iTmp < 2 + 2 * iDel + 2 * iAdd) {
00533                                 iInfoLen = 1;
00534                                 break;
00535                         }
00536                         NO_DBG_DEC(iAdd);
00537                         break;
00538                 case  16:       /* dxaRight */
00539                         pStyle->sRightIndent = (short)usGetWord(
00540                                         iFodo + iFodoOff + 1, aucGrpprl);
00541                         NO_DBG_DEC(pStyle->sRightIndent);
00542                         break;
00543                 case  17:       /* dxaLeft */
00544                         pStyle->sLeftIndent = (short)usGetWord(
00545                                         iFodo + iFodoOff + 1, aucGrpprl);
00546                         NO_DBG_DEC(pStyle->sLeftIndent);
00547                         break;
00548                 case  18:       /* Nest dxaLeft */
00549                         sTmp = (short)usGetWord(
00550                                         iFodo + iFodoOff + 1, aucGrpprl);
00551                         pStyle->sLeftIndent += sTmp;
00552                         if (pStyle->sLeftIndent < 0) {
00553                                 pStyle->sLeftIndent = 0;
00554                         }
00555                         NO_DBG_DEC(sTmp);
00556                         NO_DBG_DEC(pStyle->sLeftIndent);
00557                         break;
00558                 case  19:       /* dxaLeft1 */
00559                         pStyle->sLeftIndent1 = (short)usGetWord(
00560                                         iFodo + iFodoOff + 1, aucGrpprl);
00561                         NO_DBG_DEC(pStyle->sLeftIndent1);
00562                         break;
00563                 case  21:       /* dyaBefore */
00564                         pStyle->usBeforeIndent = usGetWord(
00565                                         iFodo + iFodoOff + 1, aucGrpprl);
00566                         NO_DBG_DEC(pStyle->usBeforeIndent);
00567                         break;
00568                 case  22:       /* dyaAfter */
00569                         pStyle->usAfterIndent = usGetWord(
00570                                         iFodo + iFodoOff + 1, aucGrpprl);
00571                         NO_DBG_DEC(pStyle->usAfterIndent);
00572                         break;
00573                 default:
00574                         break;
00575                 }
00576                 if (iInfoLen <= 0) {
00577                         iInfoLen =
00578                                 iGet6InfoLength(iFodo + iFodoOff, aucGrpprl);
00579                         fail(iInfoLen <= 0);
00580                 }
00581                 iFodoOff += iInfoLen;
00582         }
00583 } /* end of vGet6StyleInfo */
00584 
00585 /*
00586  * Build the lists with Paragraph Information for Word 6/7 files
00587  */
00588 void
00589 vGet6PapInfo(FILE *pFile, ULONG ulStartBlock,
00590         const ULONG *aulBBD, size_t tBBDLen,
00591         const UCHAR *aucHeader)
00592 {
00593         row_block_type          tRow;
00594         style_block_type        tStyle;
00595         USHORT  *ausParfPage;
00596         UCHAR   *aucBuffer;
00597         ULONG   ulCharPos, ulCharPosFirst, ulCharPosLast;
00598         ULONG   ulBeginParfInfo;
00599         size_t  tParfInfoLen, tParfPageNum, tOffset, tSize, tLenOld, tLen;
00600         size_t  tIndex, tIndex2, tRun;
00601         int     iFodo, iLen;
00602         row_info_enum   eRowInfo;
00603         USHORT  usParfFirstPage, usCount, usIstd;
00604         UCHAR   aucFpage[BIG_BLOCK_SIZE];
00605 
00606         fail(pFile == NULL || aucHeader == NULL);
00607         fail(ulStartBlock > MAX_BLOCKNUMBER && ulStartBlock != END_OF_CHAIN);
00608         fail(aulBBD == NULL);
00609 
00610         ulBeginParfInfo = ulGetLong(0xc0, aucHeader); /* fcPlcfbtePapx */
00611         NO_DBG_HEX(ulBeginParfInfo);
00612         tParfInfoLen = (size_t)ulGetLong(0xc4, aucHeader); /* lcbPlcfbtePapx */
00613         NO_DBG_DEC(tParfInfoLen);
00614         if (tParfInfoLen < 4) {
00615                 DBG_DEC(tParfInfoLen);
00616                 return;
00617         }
00618 
00619         aucBuffer = xmalloc(tParfInfoLen);
00620         if (!bReadBuffer(pFile, ulStartBlock,
00621                         aulBBD, tBBDLen, BIG_BLOCK_SIZE,
00622                         aucBuffer, ulBeginParfInfo, tParfInfoLen)) {
00623                 aucBuffer = xfree(aucBuffer);
00624                 return;
00625         }
00626         NO_DBG_PRINT_BLOCK(aucBuffer, tParfInfoLen);
00627 
00628         tLen = (tParfInfoLen - 4) / 6;
00629         ausParfPage = xcalloc(tLen, sizeof(USHORT));
00630         for (tIndex = 0, tOffset = (tLen + 1) * 4;
00631              tIndex < tLen;
00632              tIndex++, tOffset += 2) {
00633                  ausParfPage[tIndex] = usGetWord(tOffset, aucBuffer);
00634                  NO_DBG_DEC(ausParfPage[tIndex]);
00635         }
00636         DBG_HEX(ulGetLong(0, aucBuffer));
00637         aucBuffer = xfree(aucBuffer);
00638         tParfPageNum = (size_t)usGetWord(0x190, aucHeader); /* cpnBtePap */
00639         DBG_DEC(tParfPageNum);
00640         if (tLen < tParfPageNum) {
00641                 /* Replace ParfPage by a longer version */
00642                 tLenOld = tLen;
00643                 usParfFirstPage = usGetWord(0x18c, aucHeader); /* pnPapFirst */
00644                 DBG_DEC(usParfFirstPage);
00645                 tLen += tParfPageNum - 1;
00646                 tSize = tLen * sizeof(USHORT);
00647                 ausParfPage = xrealloc(ausParfPage, tSize);
00648                 /* Add new values */
00649                 usCount = usParfFirstPage + 1;
00650                 for (tIndex = tLenOld; tIndex < tLen; tIndex++) {
00651                         ausParfPage[tIndex] = usCount;
00652                         NO_DBG_DEC(ausParfPage[tIndex]);
00653                         usCount++;
00654                 }
00655         }
00656 
00657         (void)memset(&tRow, 0, sizeof(tRow));
00658         ulCharPosFirst = CP_INVALID;
00659         for (tIndex = 0; tIndex < tLen; tIndex++) {
00660                 if (!bReadBuffer(pFile, ulStartBlock,
00661                                 aulBBD, tBBDLen, BIG_BLOCK_SIZE,
00662                                 aucFpage,
00663                                 (ULONG)ausParfPage[tIndex] * BIG_BLOCK_SIZE,
00664                                 BIG_BLOCK_SIZE)) {
00665                         break;
00666                 }
00667                 tRun = (size_t)ucGetByte(0x1ff, aucFpage);
00668                 NO_DBG_DEC(tRun);
00669                 for (tIndex2 = 0; tIndex2 < tRun; tIndex2++) {
00670                         NO_DBG_HEX(ulGetLong(tIndex2 * 4, aucFpage));
00671                         iFodo = 2 * (int)ucGetByte(
00672                                 (tRun + 1) * 4 + tIndex2 * 7, aucFpage);
00673                         if (iFodo <= 0) {
00674                                 continue;
00675                         }
00676 
00677                         iLen = 2 * (int)ucGetByte(iFodo, aucFpage);
00678 
00679                         usIstd = (USHORT)ucGetByte(iFodo + 1, aucFpage);
00680                         vFillStyleFromStylesheet(usIstd, &tStyle);
00681                         vGet6StyleInfo(iFodo, aucFpage + 3, iLen - 3, &tStyle);
00682                         ulCharPos = ulGetLong(tIndex2 * 4, aucFpage);
00683                         NO_DBG_HEX(ulCharPos);
00684                         tStyle.ulFileOffset = ulCharPos2FileOffsetX(
00685                                 ulCharPos, &tStyle.eListID);
00686                         vAdd2StyleInfoList(&tStyle);
00687 
00688                         eRowInfo = eGet6RowInfo(iFodo,
00689                                         aucFpage + 3, iLen - 3, &tRow);
00690                         switch(eRowInfo) {
00691                         case found_a_cell:
00692                                 if (ulCharPosFirst != CP_INVALID) {
00693                                         break;
00694                                 }
00695                                 ulCharPosFirst = ulGetLong(
00696                                                 tIndex2 * 4, aucFpage);
00697                                 NO_DBG_HEX(ulCharPosFirst);
00698                                 tRow.ulCharPosStart = ulCharPosFirst;
00699                                 tRow.ulFileOffsetStart =
00700                                         ulCharPos2FileOffset(ulCharPosFirst);
00701                                 DBG_HEX_C(tRow.ulFileOffsetStart == FC_INVALID,
00702                                                         ulCharPosFirst);
00703                                 break;
00704                         case found_end_of_row:
00705                                 ulCharPosLast = ulGetLong(
00706                                                 tIndex2 * 4, aucFpage);
00707                                 NO_DBG_HEX(ulCharPosLast);
00708                                 tRow.ulCharPosEnd = ulCharPosLast;
00709                                 tRow.ulFileOffsetEnd =
00710                                         ulCharPos2FileOffset(ulCharPosLast);
00711                                 DBG_HEX_C(tRow.ulFileOffsetEnd == FC_INVALID,
00712                                                         ulCharPosLast);
00713                                 vAdd2RowInfoList(&tRow);
00714                                 (void)memset(&tRow, 0, sizeof(tRow));
00715                                 ulCharPosFirst = CP_INVALID;
00716                                 break;
00717                         case found_nothing:
00718                                 break;
00719                         default:
00720                                 DBG_DEC(eRowInfo);
00721                                 break;
00722                         }
00723                 }
00724         }
00725         ausParfPage = xfree(ausParfPage);
00726 } /* end of vGet6PapInfo */
00727 
00728 /*
00729  * Fill the font information block with information
00730  * from a Word 6/7 file.
00731  * Returns TRUE when successful, otherwise FALSE
00732  */
00733 void
00734 vGet6FontInfo(int iFodo, USHORT usIstd,
00735         const UCHAR *aucGrpprl, int iBytes, font_block_type *pFont)
00736 {
00737         long    lTmp;
00738         int     iFodoOff, iInfoLen;
00739         USHORT  usTmp;
00740         UCHAR   ucTmp;
00741 
00742         TRACE_MSG("vGet6FontInfo");
00743 
00744         fail(iFodo < 0 || aucGrpprl == NULL || pFont == NULL);
00745 
00746         iFodoOff = 0;
00747         while (iBytes >= iFodoOff + 1) {
00748                 switch (ucGetByte(iFodo + iFodoOff, aucGrpprl)) {
00749                 case  65:       /* fRMarkDel */
00750                         ucTmp = ucGetByte(iFodo + iFodoOff + 1, aucGrpprl);
00751                         if (ucTmp == 0) {
00752                                 pFont->usFontStyle &= ~FONT_MARKDEL;
00753                         } else {
00754                                 pFont->usFontStyle |= FONT_MARKDEL;
00755                         }
00756                         break;
00757                 case  80:       /* cIstd */
00758                         usTmp = usGetWord(iFodo + iFodoOff + 1, aucGrpprl);
00759                         NO_DBG_DEC(usTmp);
00760                         break;
00761                 case  82:       /* cDefault */
00762                         pFont->usFontStyle &= FONT_HIDDEN;
00763                         pFont->ucFontColor = FONT_COLOR_DEFAULT;
00764                         break;
00765                 case  83:       /* cPlain */
00766                         DBG_MSG("83: cPlain");
00767                         vFillFontFromStylesheet(usIstd, pFont);
00768                         break;
00769                 case  85:       /* fBold */
00770                         ucTmp = ucGetByte(iFodo + iFodoOff + 1, aucGrpprl);
00771                         switch (ucTmp) {
00772                         case   0:       /* Unset */
00773                                 pFont->usFontStyle &= ~FONT_BOLD;
00774                                 break;
00775                         case   1:       /* Set */
00776                                 pFont->usFontStyle |= FONT_BOLD;
00777                                 break;
00778                         case 128:       /* Unchanged */
00779                                 break;
00780                         case 129:       /* Negation */
00781                                 pFont->usFontStyle ^= FONT_BOLD;
00782                                 break;
00783                         default:
00784                                 DBG_DEC(ucTmp);
00785                                 DBG_FIXME();
00786                                 break;
00787                         }
00788                         break;
00789                 case  86:       /* fItalic */
00790                         ucTmp = ucGetByte(iFodo + iFodoOff + 1, aucGrpprl);
00791                         switch (ucTmp) {
00792                         case   0:       /* Unset */
00793                                 pFont->usFontStyle &= ~FONT_ITALIC;
00794                                 break;
00795                         case   1:       /* Set */
00796                                 pFont->usFontStyle |= FONT_ITALIC;
00797                                 break;
00798                         case 128:       /* Unchanged */
00799                                 break;
00800                         case 129:       /* Negation */
00801                                 pFont->usFontStyle ^= FONT_ITALIC;
00802                                 break;
00803                         default:
00804                                 DBG_DEC(ucTmp);
00805                                 DBG_FIXME();
00806                                 break;
00807                         }
00808                         break;
00809                 case  87:       /* fStrike */
00810                         ucTmp = ucGetByte(iFodo + iFodoOff + 1, aucGrpprl);
00811                         switch (ucTmp) {
00812                         case   0:       /* Unset */
00813                                 pFont->usFontStyle &= ~FONT_STRIKE;
00814                                 break;
00815                         case   1:       /* Set */
00816                                 pFont->usFontStyle |= FONT_STRIKE;
00817                                 break;
00818                         case 128:       /* Unchanged */
00819                                 break;
00820                         case 129:       /* Negation */
00821                                 pFont->usFontStyle ^= FONT_STRIKE;
00822                                 break;
00823                         default:
00824                                 DBG_DEC(ucTmp);
00825                                 DBG_FIXME();
00826                                 break;
00827                         }
00828                         break;
00829                 case  90:       /* fSmallCaps */
00830                         ucTmp = ucGetByte(iFodo + iFodoOff + 1, aucGrpprl);
00831                         switch (ucTmp) {
00832                         case   0:       /* Unset */
00833                                 pFont->usFontStyle &= ~FONT_SMALL_CAPITALS;
00834                                 break;
00835                         case   1:       /* Set */
00836                                 pFont->usFontStyle |= FONT_SMALL_CAPITALS;
00837                                 break;
00838                         case 128:       /* Unchanged */
00839                                 break;
00840                         case 129:       /* Negation */
00841                                 pFont->usFontStyle ^= FONT_SMALL_CAPITALS;
00842                                 break;
00843                         default:
00844                                 DBG_DEC(ucTmp);
00845                                 DBG_FIXME();
00846                                 break;
00847                         }
00848                         break;
00849                 case  91:       /* fCaps */
00850                         ucTmp = ucGetByte(iFodo + iFodoOff + 1, aucGrpprl);
00851                         switch (ucTmp) {
00852                         case   0:       /* Unset */
00853                                 pFont->usFontStyle &= ~FONT_CAPITALS;
00854                                 break;
00855                         case   1:       /* Set */
00856                                 pFont->usFontStyle |= FONT_CAPITALS;
00857                                 break;
00858                         case 128:       /* Unchanged */
00859                                 break;
00860                         case 129:       /* Negation */
00861                                 pFont->usFontStyle ^= FONT_CAPITALS;
00862                                 break;
00863                         default:
00864                                 DBG_DEC(ucTmp);
00865                                 DBG_FIXME();
00866                                 break;
00867                         }
00868                         break;
00869                 case  92:       /* fVanish */
00870                         ucTmp = ucGetByte(iFodo + iFodoOff + 1, aucGrpprl);
00871                         switch (ucTmp) {
00872                         case   0:       /* Unset */
00873                                 pFont->usFontStyle &= ~FONT_HIDDEN;
00874                                 break;
00875                         case   1:       /* Set */
00876                                 pFont->usFontStyle |= FONT_HIDDEN;
00877                                 break;
00878                         case 128:       /* Unchanged */
00879                                 break;
00880                         case 129:       /* Negation */
00881                                 pFont->usFontStyle ^= FONT_HIDDEN;
00882                                 break;
00883                         default:
00884                                 DBG_DEC(ucTmp);
00885                                 DBG_FIXME();
00886                                 break;
00887                         }
00888                         break;
00889                 case  93:       /* cFtc */
00890                         usTmp = usGetWord(iFodo + iFodoOff + 1, aucGrpprl);
00891                         if (usTmp <= (USHORT)UCHAR_MAX) {
00892                                 pFont->ucFontNumber = (UCHAR)usTmp;
00893                         } else {
00894                                 DBG_DEC(usTmp);
00895                                 DBG_FIXME();
00896                                 pFont->ucFontNumber = 0;
00897                         }
00898                         break;
00899                 case  94:       /* cKul */
00900                         ucTmp = ucGetByte(iFodo + iFodoOff + 1, aucGrpprl);
00901                         if (ucTmp == 0 || ucTmp == 5) {
00902                                 pFont->usFontStyle &= ~FONT_UNDERLINE;
00903                         } else {
00904                                 NO_DBG_MSG("Underline text");
00905                                 pFont->usFontStyle |= FONT_UNDERLINE;
00906                                 if (ucTmp == 6) {
00907                                         DBG_MSG("Bold text");
00908                                         pFont->usFontStyle |= FONT_BOLD;
00909                                 }
00910                         }
00911                         break;
00912                 case  95:       /* cHps, cHpsPos */
00913                         ucTmp = ucGetByte(iFodo + iFodoOff + 1, aucGrpprl);
00914                         DBG_DEC(ucTmp);
00915                         if (ucTmp != 0) {
00916                                 pFont->usFontSize = (USHORT)ucTmp;
00917                         }
00918                         ucTmp = ucGetByte(iFodo + iFodoOff + 2, aucGrpprl);
00919                         DBG_DEC(ucTmp);
00920                         break;
00921                 case  98:       /* cIco */
00922                         pFont->ucFontColor =
00923                                 ucGetByte(iFodo + iFodoOff + 1, aucGrpprl);
00924                         break;
00925                 case  99:       /* cHps */
00926                         pFont->usFontSize =
00927                                 usGetWord(iFodo + iFodoOff + 1, aucGrpprl);
00928                         break;
00929                 case 100:       /* cHpsInc */
00930                         DBG_MSG("100: sprmCHpsInc");
00931                         ucTmp = ucGetByte(iFodo + iFodoOff + 1, aucGrpprl);
00932                         DBG_DEC(ucTmp);
00933                         break;
00934                 case 103:       /* cMajority */
00935                         DBG_MSG("103: sprmCMajority");
00936                         break;
00937                 case 104:       /* cIss */
00938                         ucTmp = ucGetByte(iFodo + iFodoOff + 1, aucGrpprl);
00939                         ucTmp &= 0x07;
00940                         if (ucTmp == 1) {
00941                                 pFont->usFontStyle |= FONT_SUPERSCRIPT;
00942                                 NO_DBG_MSG("Superscript");
00943                         } else if (ucTmp == 2) {
00944                                 pFont->usFontStyle |= FONT_SUBSCRIPT;
00945                                 NO_DBG_MSG("Subscript");
00946                         }
00947                         break;
00948                 case 106:       /* cHpsInc1 */
00949                         usTmp = usGetWord(iFodo + iFodoOff + 1, aucGrpprl);
00950                         lTmp = (long)pFont->usFontSize + (long)usTmp;
00951                         if (lTmp < 8) {
00952                                 pFont->usFontSize = 8;
00953                         } else if (lTmp > 32766) {
00954                                 pFont->usFontSize = 32766;
00955                         } else {
00956                                 pFont->usFontSize = (USHORT)lTmp;
00957                         }
00958                         break;
00959                 case 108:       /* cMajority50 */
00960                         DBG_MSG("108: sprmCMajority50");
00961                         break;
00962                 case 109:       /* cHpsMul */
00963                         DBG_MSG("109: sprmCHpsMul");
00964                         usTmp = usGetWord(iFodo + iFodoOff + 1, aucGrpprl);
00965                         DBG_DEC(usTmp);
00966                         break;
00967                 default:
00968                         break;
00969                 }
00970                 iInfoLen = iGet6InfoLength(iFodo + iFodoOff, aucGrpprl);
00971                 fail(iInfoLen <= 0);
00972                 iFodoOff += iInfoLen;
00973         }
00974 } /* end of vGet6FontInfo */
00975 
00976 /*
00977  * Fill the picture information block with information
00978  * from a Word 6/7 file.
00979  * Returns TRUE when successful, otherwise FALSE
00980  */
00981 static BOOL
00982 bGet6PicInfo(int iFodo,
00983         const UCHAR *aucGrpprl, int iBytes, picture_block_type *pPicture)
00984 {
00985         int     iFodoOff, iInfoLen;
00986         BOOL    bFound;
00987         UCHAR   ucTmp;
00988 
00989         TRACE_MSG("vGet6PicInfo");
00990 
00991         fail(iFodo < 0 || aucGrpprl == NULL || pPicture == NULL);
00992 
00993         iFodoOff = 0;
00994         bFound = FALSE;
00995         while (iBytes >= iFodoOff + 1) {
00996                 switch (ucGetByte(iFodo + iFodoOff, aucGrpprl)) {
00997                 case  68:       /* fcPic */
00998                         pPicture->ulPictureOffset = ulGetLong(
00999                                         iFodo + iFodoOff + 2, aucGrpprl);
01000                         bFound = TRUE;
01001                         break;
01002 #if 0
01003                 case  71:       /* fData */
01004                         ucTmp = ucGetByte(iFodo + iFodoOff + 1, aucGrpprl);
01005                         if (ucTmp == 0x01) {
01006                                 /* Not a picture, but a form field */
01007                                 return FALSE;
01008                         }
01009                         DBG_DEC_C(ucTmp != 0, ucTmp);
01010                         break;
01011 #endif
01012                 case  75:       /* fOle2 */
01013                         ucTmp = ucGetByte(iFodo + iFodoOff + 1, aucGrpprl);
01014                         if (ucTmp == 0x01) {
01015                                 /* Not a picture, but an OLE object */
01016                                 return FALSE;
01017                         }
01018                         DBG_DEC_C(ucTmp != 0, ucTmp);
01019                         break;
01020                 default:
01021                         break;
01022                 }
01023                 iInfoLen = iGet6InfoLength(iFodo + iFodoOff, aucGrpprl);
01024                 fail(iInfoLen <= 0);
01025                 iFodoOff += iInfoLen;
01026         }
01027         return bFound;
01028 } /* end of bGet6PicInfo */
01029 
01030 /*
01031  * Build the lists with Character Information for Word 6/7 files
01032  */
01033 void
01034 vGet6ChrInfo(FILE *pFile, ULONG ulStartBlock,
01035         const ULONG *aulBBD, size_t tBBDLen, const UCHAR *aucHeader)
01036 {
01037         font_block_type         tFont;
01038         picture_block_type      tPicture;
01039         USHORT  *ausCharPage;
01040         UCHAR   *aucBuffer;
01041         ULONG   ulFileOffset, ulCharPos, ulBeginCharInfo;
01042         size_t  tCharInfoLen, tOffset, tSize, tLenOld, tLen, tCharPageNum;
01043         size_t  tIndex, tIndex2, tRun;
01044         int     iFodo, iLen;
01045         USHORT  usCharFirstPage, usCount, usIstd;
01046         UCHAR   aucFpage[BIG_BLOCK_SIZE];
01047 
01048         fail(pFile == NULL || aucHeader == NULL);
01049         fail(ulStartBlock > MAX_BLOCKNUMBER && ulStartBlock != END_OF_CHAIN);
01050         fail(aulBBD == NULL);
01051 
01052         ulBeginCharInfo = ulGetLong(0xb8, aucHeader); /* fcPlcfbteChpx */
01053         NO_DBG_HEX(lBeginCharInfo);
01054         tCharInfoLen = (size_t)ulGetLong(0xbc, aucHeader); /* lcbPlcfbteChpx */
01055         NO_DBG_DEC(tCharInfoLen);
01056         if (tCharInfoLen < 4) {
01057                 DBG_DEC(tCharInfoLen);
01058                 return;
01059         }
01060 
01061         aucBuffer = xmalloc(tCharInfoLen);
01062         if (!bReadBuffer(pFile, ulStartBlock,
01063                         aulBBD, tBBDLen, BIG_BLOCK_SIZE,
01064                         aucBuffer, ulBeginCharInfo, tCharInfoLen)) {
01065                 aucBuffer = xfree(aucBuffer);
01066                 return;
01067         }
01068 
01069         tLen = (tCharInfoLen - 4) / 6;
01070         ausCharPage = xcalloc(tLen, sizeof(USHORT));
01071         for (tIndex = 0, tOffset = (tLen + 1) * 4;
01072              tIndex < tLen;
01073              tIndex++, tOffset += 2) {
01074                  ausCharPage[tIndex] = usGetWord(tOffset, aucBuffer);
01075                  NO_DBG_DEC(ausCharPage[tIndex]);
01076         }
01077         DBG_HEX(ulGetLong(0, aucBuffer));
01078         aucBuffer = xfree(aucBuffer);
01079         tCharPageNum = (size_t)usGetWord(0x18e, aucHeader); /* cpnBteChp */
01080         DBG_DEC(tCharPageNum);
01081         if (tLen < tCharPageNum) {
01082                 /* Replace CharPage by a longer version */
01083                 tLenOld = tLen;
01084                 usCharFirstPage = usGetWord(0x18a, aucHeader); /* pnChrFirst */
01085                 DBG_DEC(usCharFirstPage);
01086                 tLen += tCharPageNum - 1;
01087                 tSize = tLen * sizeof(USHORT);
01088                 ausCharPage = xrealloc(ausCharPage, tSize);
01089                 /* Add new values */
01090                 usCount = usCharFirstPage + 1;
01091                 for (tIndex = tLenOld; tIndex < tLen; tIndex++) {
01092                         ausCharPage[tIndex] = usCount;
01093                         NO_DBG_DEC(ausCharPage[tIndex]);
01094                         usCount++;
01095                 }
01096         }
01097 
01098         for (tIndex = 0; tIndex < tLen; tIndex++) {
01099                 if (!bReadBuffer(pFile, ulStartBlock,
01100                                 aulBBD, tBBDLen, BIG_BLOCK_SIZE,
01101                                 aucFpage,
01102                                 (ULONG)ausCharPage[tIndex] * BIG_BLOCK_SIZE,
01103                                 BIG_BLOCK_SIZE)) {
01104                         break;
01105                 }
01106                 tRun = (size_t)ucGetByte(0x1ff, aucFpage);
01107                 NO_DBG_DEC(tRun);
01108                 for (tIndex2 = 0; tIndex2 < tRun; tIndex2++) {
01109                         ulCharPos = ulGetLong(tIndex2 * 4, aucFpage);
01110                         ulFileOffset = ulCharPos2FileOffset(ulCharPos);
01111                         iFodo = 2 * (int)ucGetByte(
01112                                 (tRun + 1) * 4 + tIndex2, aucFpage);
01113 
01114                         iLen = (int)ucGetByte(iFodo, aucFpage);
01115 
01116                         usIstd = usGetIstd(ulFileOffset);
01117                         vFillFontFromStylesheet(usIstd, &tFont);
01118                         if (iFodo != 0) {
01119                                 vGet6FontInfo(iFodo, usIstd,
01120                                         aucFpage + 1, iLen - 1, &tFont);
01121                         }
01122                         tFont.ulFileOffset = ulFileOffset;
01123                         vAdd2FontInfoList(&tFont);
01124 
01125                         if (iFodo <= 0) {
01126                                 continue;
01127                         }
01128 
01129                         (void)memset(&tPicture, 0, sizeof(tPicture));
01130                         if (bGet6PicInfo(iFodo, aucFpage + 1,
01131                                                 iLen - 1, &tPicture)) {
01132                                 tPicture.ulFileOffset = ulFileOffset;
01133                                 tPicture.ulFileOffsetPicture =
01134                                         ulDataPos2FileOffset(
01135                                                 tPicture.ulPictureOffset);
01136                                 vAdd2PictInfoList(&tPicture);
01137                         }
01138                 }
01139         }
01140         ausCharPage = xfree(ausCharPage);
01141 } /* end of vGet6ChrInfo */

Generated by  doxygen 1.6.2