Imported from antiword-0.37.tar.gz.
[antiword.git] / notes.c
blobffc75266a004e969f7de5cc73eedb28188372985
1 /*
2 * notes.c
3 * Copyright (C) 1998-2005 A.J. van Os; Released under GNU GPL
5 * Description:
6 * Functions to tell the difference between footnotes and endnotes
7 */
9 #include "antiword.h"
12 * Private structures to hide the way the information
13 * is stored from the rest of the program
15 typedef struct footnote_local_tag {
16 footnote_block_type tInfo;
17 ULONG ulCharPosStart;
18 ULONG ulCharPosNext;
19 BOOL bUseful;
20 } footnote_local_type;
22 /* Variables needed to write the Footnote and Endnote information */
23 static ULONG *aulFootnoteList = NULL;
24 static size_t tFootnoteListLength = 0;
25 static ULONG *aulEndnoteList = NULL;
26 static size_t tEndnoteListLength = 0;
27 /* Variables needed to write the Footnote Text */
28 static footnote_local_type *pFootnoteText = NULL;
29 static size_t tFootnoteTextLength = 0;
33 * Destroy the lists with footnote and endnote information
35 void
36 vDestroyNotesInfoLists(void)
38 footnote_local_type *pRecord;
39 size_t tFootnote;
41 TRACE_MSG("vDestroyNotesInfoLists");
43 /* Free the lists and reset all control variables */
44 aulEndnoteList = xfree(aulEndnoteList);
45 aulFootnoteList = xfree(aulFootnoteList);
46 tEndnoteListLength = 0;
47 tFootnoteListLength = 0;
48 for (tFootnote = 0; tFootnote < tFootnoteTextLength; tFootnote++) {
49 pRecord = pFootnoteText + tFootnote;
50 pRecord->tInfo.szText = xfree(pRecord->tInfo.szText);
52 pFootnoteText = xfree(pFootnoteText);
53 tFootnoteTextLength = 0;
54 } /* end of vDestroyNotesInfoLists */
57 * Build the list with footnote information for Word for DOS files
59 static void
60 vGet0FootnotesInfoAndText(FILE *pFile, const UCHAR *aucHeader)
62 footnote_local_type *pCurr;
63 UCHAR *aucBuffer;
64 ULONG ulFileOffset, ulBeginOfText, ulOffset, ulBeginFootnoteInfo;
65 ULONG ulCharPos, ulBeginNextBlock;
66 size_t tFootnotes, tFootnoteInfoLen;
67 size_t tIndex;
68 UCHAR aucTmp[2];
70 TRACE_MSG("vGet0FootnotesInfoAndText");
72 fail(pFile == NULL || aucHeader == NULL);
74 ulBeginOfText = 128;
75 NO_DBG_HEX(ulBeginOfText);
76 ulBeginFootnoteInfo = 128 * (ULONG)usGetWord(0x14, aucHeader);
77 DBG_HEX(ulBeginFootnoteInfo);
78 ulBeginNextBlock = 128 * (ULONG)usGetWord(0x16, aucHeader);
79 DBG_HEX(ulBeginNextBlock);
81 if (ulBeginFootnoteInfo == ulBeginNextBlock) {
82 DBG_MSG("No Footnotes in this document");
83 return;
86 /* Read the the number of footnotes + 1 */
87 if (!bReadBytes(aucTmp, 2, ulBeginFootnoteInfo, pFile)) {
88 return;
90 tFootnotes = (size_t)usGetWord(0, aucTmp);
91 if (tFootnotes < 2) {
92 DBG_MSG("No Footnotes in this document (2)");
94 DBG_DEC(tFootnotes);
95 tFootnoteInfoLen = 8 * tFootnotes;
97 aucBuffer = xmalloc(tFootnoteInfoLen);
98 if (!bReadBytes(aucBuffer,
99 tFootnoteInfoLen, ulBeginFootnoteInfo + 4, pFile)) {
100 aucBuffer = xfree(aucBuffer);
101 return;
103 DBG_PRINT_BLOCK(aucBuffer, tFootnoteInfoLen);
105 /* Get footnote information */
106 fail(tFootnoteListLength != 0);
107 tFootnoteListLength = tFootnotes - 1;
108 fail(tFootnoteListLength == 0);
110 fail(aulFootnoteList != NULL);
111 aulFootnoteList = xcalloc(tFootnoteListLength, sizeof(ULONG));
113 for (tIndex = 0; tIndex < tFootnoteListLength; tIndex++) {
114 ulOffset = ulGetLong(tIndex * 8, aucBuffer);
115 DBG_HEX(ulOffset);
116 ulFileOffset = ulCharPos2FileOffset(ulBeginOfText + ulOffset);
117 DBG_HEX(ulFileOffset);
118 aulFootnoteList[tIndex] = ulFileOffset;
121 /* Get footnote text */
122 fail(tFootnoteTextLength != 0);
123 tFootnoteTextLength = tFootnotes - 1;
124 fail(tFootnoteTextLength == 0);
126 fail(pFootnoteText != NULL);
127 pFootnoteText = xcalloc(tFootnoteTextLength,
128 sizeof(footnote_local_type));
130 for (tIndex = 0; tIndex < tFootnoteTextLength; tIndex++) {
131 pCurr = pFootnoteText + tIndex;
132 pCurr->tInfo.szText = NULL;
133 ulOffset = ulGetLong(tIndex * 8 + 4, aucBuffer);
134 DBG_HEX(ulOffset);
135 ulCharPos = ulBeginOfText + ulOffset;
136 DBG_HEX(ulCharPos);
137 DBG_HEX(ulCharPos2FileOffset(ulCharPos));
138 pCurr->ulCharPosStart = ulCharPos;
139 ulOffset = ulGetLong((tIndex + 1) * 8 + 4, aucBuffer);
140 DBG_HEX(ulOffset);
141 ulCharPos = ulBeginOfText + ulOffset;
142 DBG_HEX(ulCharPos);
143 DBG_HEX(ulCharPos2FileOffset(ulCharPos));
144 pCurr->ulCharPosNext = ulCharPos;
145 pCurr->bUseful = pCurr->ulCharPosStart != pCurr->ulCharPosNext;
147 aucBuffer = xfree(aucBuffer);
148 } /* end of vGet0FootnotesInfoAndText */
151 * Build the lists note information for Word for DOS files
153 static void
154 vGet0NotesInfo(FILE *pFile, const UCHAR *aucHeader)
156 TRACE_MSG("vGet0NotesInfo");
158 vGet0FootnotesInfoAndText(pFile, aucHeader);
159 /* There are no endnotes in a Word for DOS file */
160 } /* end of vGet0NotesInfo */
163 * Build the list with footnote information for WinWord 1/2 files
165 static void
166 vGet2FootnotesInfo(FILE *pFile, const UCHAR *aucHeader)
168 UCHAR *aucBuffer;
169 ULONG ulFileOffset, ulBeginOfText, ulOffset, ulBeginFootnoteInfo;
170 size_t tFootnoteInfoLen;
171 size_t tIndex;
173 TRACE_MSG("vGet2FootnotesInfo");
175 fail(pFile == NULL || aucHeader == NULL);
177 ulBeginOfText = ulGetLong(0x18, aucHeader); /* fcMin */
178 NO_DBG_HEX(ulBeginOfText);
179 ulBeginFootnoteInfo = ulGetLong(0x64, aucHeader); /* fcPlcffndRef */
180 NO_DBG_HEX(ulBeginFootnoteInfo);
181 tFootnoteInfoLen = (size_t)usGetWord(0x68, aucHeader); /* cbPlcffndRef */
182 NO_DBG_DEC(tFootnoteInfoLen);
184 if (tFootnoteInfoLen < 10) {
185 DBG_MSG("No Footnotes in this document");
186 return;
189 aucBuffer = xmalloc(tFootnoteInfoLen);
190 if (!bReadBytes(aucBuffer,
191 tFootnoteInfoLen, ulBeginFootnoteInfo, pFile)) {
192 aucBuffer = xfree(aucBuffer);
193 return;
195 NO_DBG_PRINT_BLOCK(aucBuffer, tFootnoteInfoLen);
197 fail(tFootnoteListLength != 0);
198 tFootnoteListLength = (tFootnoteInfoLen - 4) / 6;
199 fail(tFootnoteListLength == 0);
201 fail(aulFootnoteList != NULL);
202 aulFootnoteList = xcalloc(tFootnoteListLength, sizeof(ULONG));
204 for (tIndex = 0; tIndex < tFootnoteListLength; tIndex++) {
205 ulOffset = ulGetLong(tIndex * 4, aucBuffer);
206 NO_DBG_HEX(ulOffset);
207 ulFileOffset = ulCharPos2FileOffset(ulBeginOfText + ulOffset);
208 NO_DBG_HEX(ulFileOffset);
209 aulFootnoteList[tIndex] = ulFileOffset;
211 aucBuffer = xfree(aucBuffer);
212 } /* end of vGet2FootnotesInfo */
215 * Build the list with footnote text information for WinWord 1/2 files
217 static void
218 vGet2FootnotesText(FILE *pFile, const UCHAR *aucHeader)
220 footnote_local_type *pCurr;
221 UCHAR *aucBuffer;
222 ULONG ulCharPos, ulBeginOfFootnotes, ulOffset, ulBeginFootnoteText;
223 size_t tFootnoteTextLen;
224 size_t tIndex;
226 TRACE_MSG("vGet2FootnotesText");
228 fail(pFile == NULL || aucHeader == NULL);
230 ulBeginOfFootnotes = ulGetLong(0x18, aucHeader); /* fcMin */
231 ulBeginOfFootnotes += ulGetLong(0x34, aucHeader); /* ccpText */
232 NO_DBG_HEX(ulBeginOfFootnotes);
234 ulBeginFootnoteText = ulGetLong(0x6a, aucHeader); /* fcPlcffndTxt */
235 NO_DBG_HEX(ulBeginFootnoteText);
236 tFootnoteTextLen =
237 (size_t)usGetWord(0x6e, aucHeader); /* cbPlcffndTxt */
238 NO_DBG_DEC(tFootnoteTextLen);
240 if (tFootnoteTextLen < 12) {
241 DBG_MSG("No Footnote text in this document");
242 return;
245 aucBuffer = xmalloc(tFootnoteTextLen);
246 if (!bReadBytes(aucBuffer,
247 tFootnoteTextLen, ulBeginFootnoteText, pFile)) {
248 aucBuffer = xfree(aucBuffer);
249 return;
251 NO_DBG_PRINT_BLOCK(aucBuffer, tFootnoteTextLen);
253 fail(tFootnoteTextLength != 0);
254 tFootnoteTextLength = tFootnoteTextLen / 4 - 2;
255 fail(tFootnoteTextLength == 0);
257 fail(pFootnoteText != NULL);
258 pFootnoteText = xcalloc(tFootnoteTextLength,
259 sizeof(footnote_local_type));
261 for (tIndex = 0; tIndex < tFootnoteTextLength; tIndex++) {
262 pCurr = pFootnoteText + tIndex;
263 pCurr->tInfo.szText = NULL;
264 ulOffset = ulGetLong(tIndex * 4, aucBuffer);
265 NO_DBG_HEX(ulOffset);
266 ulCharPos = ulBeginOfFootnotes + ulOffset;
267 NO_DBG_HEX(ulCharPos);
268 NO_DBG_HEX(ulCharPos2FileOffset(ulCharPos));
269 pCurr->ulCharPosStart = ulCharPos;
270 ulOffset = ulGetLong(tIndex * 4 + 4, aucBuffer);
271 NO_DBG_HEX(ulOffset);
272 ulCharPos = ulBeginOfFootnotes + ulOffset;
273 NO_DBG_HEX(ulCharPos);
274 NO_DBG_HEX(ulCharPos2FileOffset(ulCharPos));
275 pCurr->ulCharPosNext = ulCharPos;
276 pCurr->bUseful = pCurr->ulCharPosStart != pCurr->ulCharPosNext;
278 aucBuffer = xfree(aucBuffer);
279 } /* end of vGet2FootnotesText */
282 * Build the lists note information for WinWord 1/2 files
284 static void
285 vGet2NotesInfo(FILE *pFile, const UCHAR *aucHeader)
287 TRACE_MSG("vGet2NotesInfo");
289 vGet2FootnotesInfo(pFile, aucHeader);
290 vGet2FootnotesText(pFile, aucHeader);
291 /* There are no endnotes in a WinWord 1/2 file */
292 } /* end of vGet2NotesInfo */
295 * Build the list with footnote information for Word 6/7 files
297 static void
298 vGet6FootnotesInfo(FILE *pFile, ULONG ulStartBlock,
299 const ULONG *aulBBD, size_t tBBDLen,
300 const UCHAR *aucHeader)
302 UCHAR *aucBuffer;
303 ULONG ulFileOffset, ulBeginOfText, ulOffset, ulBeginFootnoteInfo;
304 size_t tFootnoteInfoLen;
305 size_t tIndex;
307 TRACE_MSG("vGet6FootnotesInfo");
309 fail(pFile == NULL || aucHeader == NULL);
310 fail(ulStartBlock > MAX_BLOCKNUMBER && ulStartBlock != END_OF_CHAIN);
311 fail(aulBBD == NULL);
313 ulBeginOfText = ulGetLong(0x18, aucHeader); /* fcMin */
314 NO_DBG_HEX(ulBeginOfText);
315 ulBeginFootnoteInfo = ulGetLong(0x68, aucHeader); /* fcPlcffndRef */
316 NO_DBG_HEX(ulBeginFootnoteInfo);
317 tFootnoteInfoLen =
318 (size_t)ulGetLong(0x6c, aucHeader); /* lcbPlcffndRef */
319 NO_DBG_DEC(tFootnoteInfoLen);
321 if (tFootnoteInfoLen < 10) {
322 DBG_MSG("No Footnotes in this document");
323 return;
326 aucBuffer = xmalloc(tFootnoteInfoLen);
327 if (!bReadBuffer(pFile, ulStartBlock,
328 aulBBD, tBBDLen, BIG_BLOCK_SIZE,
329 aucBuffer, ulBeginFootnoteInfo, tFootnoteInfoLen)) {
330 aucBuffer = xfree(aucBuffer);
331 return;
333 NO_DBG_PRINT_BLOCK(aucBuffer, tFootnoteInfoLen);
335 fail(tFootnoteListLength != 0);
336 tFootnoteListLength = (tFootnoteInfoLen - 4) / 6;
337 fail(tFootnoteListLength == 0);
339 fail(aulFootnoteList != NULL);
340 aulFootnoteList = xcalloc(tFootnoteListLength, sizeof(ULONG));
342 for (tIndex = 0; tIndex < tFootnoteListLength; tIndex++) {
343 ulOffset = ulGetLong(tIndex * 4, aucBuffer);
344 NO_DBG_HEX(ulOffset);
345 ulFileOffset = ulCharPos2FileOffset(ulBeginOfText + ulOffset);
346 NO_DBG_HEX(ulFileOffset);
347 aulFootnoteList[tIndex] = ulFileOffset;
349 aucBuffer = xfree(aucBuffer);
350 } /* end of vGet6FootnotesInfo */
353 * Build the list with footnote text information for Word 6/7 files
355 static void
356 vGet6FootnotesText(FILE *pFile, ULONG ulStartBlock,
357 const ULONG *aulBBD, size_t tBBDLen,
358 const UCHAR *aucHeader)
360 footnote_local_type *pCurr;
361 UCHAR *aucBuffer;
362 ULONG ulCharPos, ulBeginOfFootnotes, ulOffset, ulBeginFootnoteText;
363 size_t tFootnoteTextLen;
364 size_t tIndex;
366 TRACE_MSG("vGet6FootnotesText");
368 fail(pFile == NULL || aucHeader == NULL);
369 fail(ulStartBlock > MAX_BLOCKNUMBER && ulStartBlock != END_OF_CHAIN);
370 fail(aulBBD == NULL);
372 ulBeginOfFootnotes = ulGetLong(0x18, aucHeader); /* fcMin */
373 ulBeginOfFootnotes += ulGetLong(0x34, aucHeader); /* ccpText */
374 NO_DBG_HEX(ulBeginOfFootnotes);
376 ulBeginFootnoteText = ulGetLong(0x70, aucHeader); /* fcPlcffndTxt */
377 NO_DBG_HEX(ulBeginFootnoteText);
378 tFootnoteTextLen =
379 (size_t)ulGetLong(0x74, aucHeader); /* lcbPlcffndTxt */
380 NO_DBG_DEC(tFootnoteTextLen);
382 if (tFootnoteTextLen < 12) {
383 DBG_MSG("No Footnote text in this document");
384 return;
387 aucBuffer = xmalloc(tFootnoteTextLen);
388 if (!bReadBuffer(pFile, ulStartBlock,
389 aulBBD, tBBDLen, BIG_BLOCK_SIZE,
390 aucBuffer, ulBeginFootnoteText, tFootnoteTextLen)) {
391 aucBuffer = xfree(aucBuffer);
392 return;
394 NO_DBG_PRINT_BLOCK(aucBuffer, tFootnoteTextLen);
396 fail(tFootnoteTextLength != 0);
397 tFootnoteTextLength = tFootnoteTextLen / 4 - 2;
398 fail(tFootnoteTextLength == 0);
400 fail(pFootnoteText != NULL);
401 pFootnoteText = xcalloc(tFootnoteTextLength,
402 sizeof(footnote_local_type));
404 for (tIndex = 0; tIndex < tFootnoteTextLength; tIndex++) {
405 pCurr = pFootnoteText + tIndex;
406 pCurr->tInfo.szText = NULL;
407 ulOffset = ulGetLong(tIndex * 4, aucBuffer);
408 NO_DBG_HEX(ulOffset);
409 ulCharPos = ulBeginOfFootnotes + ulOffset;
410 NO_DBG_HEX(ulCharPos);
411 NO_DBG_HEX(ulCharPos2FileOffset(ulCharPos));
412 pCurr->ulCharPosStart = ulCharPos;
413 ulOffset = ulGetLong(tIndex * 4 + 4, aucBuffer);
414 NO_DBG_HEX(ulOffset);
415 ulCharPos = ulBeginOfFootnotes + ulOffset;
416 NO_DBG_HEX(ulCharPos);
417 NO_DBG_HEX(ulCharPos2FileOffset(ulCharPos));
418 pCurr->ulCharPosNext = ulCharPos;
419 pCurr->bUseful = pCurr->ulCharPosStart != pCurr->ulCharPosNext;
421 aucBuffer = xfree(aucBuffer);
422 } /* end of vGet6FootnotesText */
425 * Build the list with endnote information for Word 6/7 files
427 static void
428 vGet6EndnotesInfo(FILE *pFile, ULONG ulStartBlock,
429 const ULONG *aulBBD, size_t tBBDLen,
430 const UCHAR *aucHeader)
432 UCHAR *aucBuffer;
433 ULONG ulFileOffset, ulBeginOfText, ulOffset, ulBeginEndnoteInfo;
434 size_t tEndnoteInfoLen;
435 size_t tIndex;
437 TRACE_MSG("vGet6EndnotesInfo");
439 fail(pFile == NULL || aucHeader == NULL);
440 fail(ulStartBlock > MAX_BLOCKNUMBER && ulStartBlock != END_OF_CHAIN);
441 fail(aulBBD == NULL);
443 ulBeginOfText = ulGetLong(0x18, aucHeader); /* fcMin */
444 NO_DBG_HEX(ulBeginOfText);
445 ulBeginEndnoteInfo = ulGetLong(0x1d2, aucHeader); /* fcPlcfendRef */
446 NO_DBG_HEX(ulBeginEndnoteInfo);
447 tEndnoteInfoLen =
448 (size_t)ulGetLong(0x1d6, aucHeader); /* lcbPlcfendRef */
449 NO_DBG_DEC(tEndnoteInfoLen);
451 if (tEndnoteInfoLen < 10) {
452 DBG_MSG("No Endnotes in this document");
453 return;
456 aucBuffer = xmalloc(tEndnoteInfoLen);
457 if (!bReadBuffer(pFile, ulStartBlock,
458 aulBBD, tBBDLen, BIG_BLOCK_SIZE,
459 aucBuffer, ulBeginEndnoteInfo, tEndnoteInfoLen)) {
460 aucBuffer = xfree(aucBuffer);
461 return;
463 NO_DBG_PRINT_BLOCK(aucBuffer, tEndnoteInfoLen);
465 fail(tEndnoteListLength != 0);
466 tEndnoteListLength = (tEndnoteInfoLen - 4) / 6;
467 fail(tEndnoteListLength == 0);
469 fail(aulEndnoteList != NULL);
470 aulEndnoteList = xcalloc(tEndnoteListLength, sizeof(ULONG));
472 for (tIndex = 0; tIndex < tEndnoteListLength; tIndex++) {
473 ulOffset = ulGetLong(tIndex * 4, aucBuffer);
474 NO_DBG_HEX(ulOffset);
475 ulFileOffset = ulCharPos2FileOffset(ulBeginOfText + ulOffset);
476 NO_DBG_HEX(ulFileOffset);
477 aulEndnoteList[tIndex] = ulFileOffset;
479 aucBuffer = xfree(aucBuffer);
480 } /* end of vGet6EndnotesInfo */
483 * Build the lists note information for Word 6/7 files
485 static void
486 vGet6NotesInfo(FILE *pFile, ULONG ulStartBlock,
487 const ULONG *aulBBD, size_t tBBDLen,
488 const UCHAR *aucHeader)
490 TRACE_MSG("vGet6NotesInfo");
492 vGet6FootnotesInfo(pFile, ulStartBlock,
493 aulBBD, tBBDLen, aucHeader);
494 vGet6FootnotesText(pFile, ulStartBlock,
495 aulBBD, tBBDLen, aucHeader);
496 vGet6EndnotesInfo(pFile, ulStartBlock,
497 aulBBD, tBBDLen, aucHeader);
498 } /* end of vGet6NotesInfo */
501 * Build the list with footnote information for Word 8/9/10 files
503 static void
504 vGet8FootnotesInfo(FILE *pFile, const pps_info_type *pPPS,
505 const ULONG *aulBBD, size_t tBBDLen,
506 const ULONG *aulSBD, size_t tSBDLen,
507 const UCHAR *aucHeader)
509 const ULONG *aulBlockDepot;
510 UCHAR *aucBuffer;
511 ULONG ulFileOffset, ulBeginOfText, ulOffset, ulBeginFootnoteInfo;
512 size_t tFootnoteInfoLen, tBlockDepotLen, tBlockSize;
513 size_t tIndex;
515 TRACE_MSG("vGet8FootnotesInfo");
517 ulBeginOfText = ulGetLong(0x18, aucHeader); /* fcMin */
518 NO_DBG_HEX(ulBeginOfText);
519 ulBeginFootnoteInfo = ulGetLong(0xaa, aucHeader); /* fcPlcffndRef */
520 NO_DBG_HEX(ulBeginFootnoteInfo);
521 tFootnoteInfoLen =
522 (size_t)ulGetLong(0xae, aucHeader); /* lcbPlcffndRef */
523 NO_DBG_DEC(tFootnoteInfoLen);
525 if (tFootnoteInfoLen < 10) {
526 DBG_MSG("No Footnotes in this document");
527 return;
530 NO_DBG_DEC(pPPS->tTable.ulSB);
531 NO_DBG_HEX(pPPS->tTable.ulSize);
532 if (pPPS->tTable.ulSize == 0) {
533 DBG_MSG("No footnotes information");
534 return;
537 if (pPPS->tTable.ulSize < MIN_SIZE_FOR_BBD_USE) {
538 /* Use the Small Block Depot */
539 aulBlockDepot = aulSBD;
540 tBlockDepotLen = tSBDLen;
541 tBlockSize = SMALL_BLOCK_SIZE;
542 } else {
543 /* Use the Big Block Depot */
544 aulBlockDepot = aulBBD;
545 tBlockDepotLen = tBBDLen;
546 tBlockSize = BIG_BLOCK_SIZE;
548 aucBuffer = xmalloc(tFootnoteInfoLen);
549 if (!bReadBuffer(pFile, pPPS->tTable.ulSB,
550 aulBlockDepot, tBlockDepotLen, tBlockSize,
551 aucBuffer, ulBeginFootnoteInfo, tFootnoteInfoLen)) {
552 aucBuffer = xfree(aucBuffer);
553 return;
555 NO_DBG_PRINT_BLOCK(aucBuffer, tFootnoteInfoLen);
557 fail(tFootnoteListLength != 0);
558 tFootnoteListLength = (tFootnoteInfoLen - 4) / 6;
559 fail(tFootnoteListLength == 0);
561 fail(aulFootnoteList != NULL);
562 aulFootnoteList = xcalloc(tFootnoteListLength, sizeof(ULONG));
564 for (tIndex = 0; tIndex < tFootnoteListLength; tIndex++) {
565 ulOffset = ulGetLong(tIndex * 4, aucBuffer);
566 NO_DBG_HEX(ulOffset);
567 ulFileOffset = ulCharPos2FileOffset(ulBeginOfText + ulOffset);
568 NO_DBG_HEX(ulFileOffset);
569 aulFootnoteList[tIndex] = ulFileOffset;
571 aucBuffer = xfree(aucBuffer);
572 } /* end of vGet8FootnotesInfo */
575 * Build the list with footnote text information for Word 8/9/10 files
577 static void
578 vGet8FootnotesText(FILE *pFile, const pps_info_type *pPPS,
579 const ULONG *aulBBD, size_t tBBDLen,
580 const ULONG *aulSBD, size_t tSBDLen,
581 const UCHAR *aucHeader)
583 footnote_local_type *pCurr;
584 const ULONG *aulBlockDepot;
585 UCHAR *aucBuffer;
586 ULONG ulCharPos, ulBeginOfFootnotes, ulOffset, ulBeginFootnoteText;
587 size_t tFootnoteTextLen, tBlockDepotLen, tBlockSize;
588 size_t tIndex;
590 TRACE_MSG("vGet8FootnotesText");
592 ulBeginOfFootnotes = ulGetLong(0x18, aucHeader); /* fcMin */
593 ulBeginOfFootnotes += ulGetLong(0x4c, aucHeader); /* ccpText */
594 NO_DBG_HEX(ulBeginOfFootnotes);
596 ulBeginFootnoteText = ulGetLong(0xb2, aucHeader); /* fcPlcffndTxt */
597 NO_DBG_HEX(ulBeginFootnoteText);
598 tFootnoteTextLen =
599 (size_t)ulGetLong(0xb6, aucHeader); /* lcbPlcffndTxt */
600 NO_DBG_DEC(tFootnoteTextLen);
602 if (tFootnoteTextLen < 12) {
603 DBG_MSG("No Footnote text in this document");
604 return;
607 NO_DBG_DEC(pPPS->tTable.ulSB);
608 NO_DBG_HEX(pPPS->tTable.ulSize);
609 if (pPPS->tTable.ulSize == 0) {
610 DBG_MSG("No footnote text information");
611 return;
614 if (pPPS->tTable.ulSize < MIN_SIZE_FOR_BBD_USE) {
615 /* Use the Small Block Depot */
616 aulBlockDepot = aulSBD;
617 tBlockDepotLen = tSBDLen;
618 tBlockSize = SMALL_BLOCK_SIZE;
619 } else {
620 /* Use the Big Block Depot */
621 aulBlockDepot = aulBBD;
622 tBlockDepotLen = tBBDLen;
623 tBlockSize = BIG_BLOCK_SIZE;
625 aucBuffer = xmalloc(tFootnoteTextLen);
626 if (!bReadBuffer(pFile, pPPS->tTable.ulSB,
627 aulBlockDepot, tBlockDepotLen, tBlockSize,
628 aucBuffer, ulBeginFootnoteText, tFootnoteTextLen)) {
629 aucBuffer = xfree(aucBuffer);
630 return;
632 NO_DBG_PRINT_BLOCK(aucBuffer, tFootnoteTextLen);
634 fail(tFootnoteTextLength != 0);
635 tFootnoteTextLength = tFootnoteTextLen / 4 - 2;
636 fail(tFootnoteTextLength == 0);
638 fail(pFootnoteText != NULL);
639 pFootnoteText = xcalloc(tFootnoteTextLength,
640 sizeof(footnote_local_type));
642 for (tIndex = 0; tIndex < tFootnoteTextLength; tIndex++) {
643 pCurr = pFootnoteText + tIndex;
644 pCurr->tInfo.szText = NULL;
645 ulOffset = ulGetLong(tIndex * 4, aucBuffer);
646 NO_DBG_HEX(ulOffset);
647 ulCharPos = ulBeginOfFootnotes + ulOffset;
648 NO_DBG_HEX(ulCharPos);
649 NO_DBG_HEX(ulCharPos2FileOffset(ulCharPos));
650 pCurr->ulCharPosStart = ulCharPos;
651 ulOffset = ulGetLong(tIndex * 4 + 4, aucBuffer);
652 NO_DBG_HEX(ulOffset);
653 ulCharPos = ulBeginOfFootnotes + ulOffset;
654 NO_DBG_HEX(ulCharPos);
655 NO_DBG_HEX(ulCharPos2FileOffset(ulCharPos));
656 pCurr->ulCharPosNext = ulCharPos;
657 pCurr->bUseful = pCurr->ulCharPosStart != pCurr->ulCharPosNext;
659 aucBuffer = xfree(aucBuffer);
660 } /* end of vGet8FootnotesText */
663 * Build the list with endnote information for Word 8/9/10 files
665 static void
666 vGet8EndnotesInfo(FILE *pFile, const pps_info_type *pPPS,
667 const ULONG *aulBBD, size_t tBBDLen,
668 const ULONG *aulSBD, size_t tSBDLen,
669 const UCHAR *aucHeader)
671 const ULONG *aulBlockDepot;
672 UCHAR *aucBuffer;
673 ULONG ulFileOffset, ulBeginOfText, ulOffset, ulBeginEndnoteInfo;
674 size_t tEndnoteInfoLen, tBlockDepotLen, tBlockSize;
675 size_t tIndex;
677 TRACE_MSG("vGet8EndnotesInfo");
679 ulBeginOfText = ulGetLong(0x18, aucHeader); /* fcMin */
680 NO_DBG_HEX(ulBeginOfText);
681 ulBeginEndnoteInfo = ulGetLong(0x20a, aucHeader); /* fcPlcfendRef */
682 NO_DBG_HEX(ulBeginEndnoteInfo);
683 tEndnoteInfoLen = (size_t)ulGetLong(0x20e, aucHeader); /* lcbPlcfendRef */
684 NO_DBG_DEC(tEndnoteInfoLen);
686 if (tEndnoteInfoLen < 10) {
687 DBG_MSG("No endnotes in this document");
688 return;
691 NO_DBG_DEC(pPPS->tTable.ulSB);
692 NO_DBG_HEX(pPPS->tTable.ulSize);
693 if (pPPS->tTable.ulSize == 0) {
694 DBG_MSG("No endnotes information");
695 return;
698 if (pPPS->tTable.ulSize < MIN_SIZE_FOR_BBD_USE) {
699 /* Use the Small Block Depot */
700 aulBlockDepot = aulSBD;
701 tBlockDepotLen = tSBDLen;
702 tBlockSize = SMALL_BLOCK_SIZE;
703 } else {
704 /* Use the Big Block Depot */
705 aulBlockDepot = aulBBD;
706 tBlockDepotLen = tBBDLen;
707 tBlockSize = BIG_BLOCK_SIZE;
709 aucBuffer = xmalloc(tEndnoteInfoLen);
710 if (!bReadBuffer(pFile, pPPS->tTable.ulSB,
711 aulBlockDepot, tBlockDepotLen, tBlockSize,
712 aucBuffer, ulBeginEndnoteInfo, tEndnoteInfoLen)) {
713 aucBuffer = xfree(aucBuffer);
714 return;
716 NO_DBG_PRINT_BLOCK(aucBuffer, tEndnoteInfoLen);
718 fail(tEndnoteListLength != 0);
719 tEndnoteListLength = (tEndnoteInfoLen - 4) / 6;
720 fail(tEndnoteListLength == 0);
722 fail(aulEndnoteList != NULL);
723 aulEndnoteList = xcalloc(tEndnoteListLength, sizeof(ULONG));
725 for (tIndex = 0; tIndex < tEndnoteListLength; tIndex++) {
726 ulOffset = ulGetLong(tIndex * 4, aucBuffer);
727 NO_DBG_HEX(ulOffset);
728 ulFileOffset = ulCharPos2FileOffset(ulBeginOfText + ulOffset);
729 NO_DBG_HEX(ulFileOffset);
730 aulEndnoteList[tIndex] = ulFileOffset;
732 aucBuffer = xfree(aucBuffer);
733 } /* end of vGet8EndnotesInfo */
736 * Build the lists with footnote and endnote information for Word 8/9/10 files
738 static void
739 vGet8NotesInfo(FILE *pFile, const pps_info_type *pPPS,
740 const ULONG *aulBBD, size_t tBBDLen,
741 const ULONG *aulSBD, size_t tSBDLen,
742 const UCHAR *aucHeader)
744 TRACE_MSG("vGet8NotesInfo");
746 vGet8FootnotesInfo(pFile, pPPS,
747 aulBBD, tBBDLen, aulSBD, tSBDLen, aucHeader);
748 vGet8FootnotesText(pFile, pPPS,
749 aulBBD, tBBDLen, aulSBD, tSBDLen, aucHeader);
750 vGet8EndnotesInfo(pFile, pPPS,
751 aulBBD, tBBDLen, aulSBD, tSBDLen, aucHeader);
752 } /* end of vGet8NotesInfo */
755 * Build the lists with footnote and endnote information
757 void
758 vGetNotesInfo(FILE *pFile, const pps_info_type *pPPS,
759 const ULONG *aulBBD, size_t tBBDLen,
760 const ULONG *aulSBD, size_t tSBDLen,
761 const UCHAR *aucHeader, int iWordVersion)
763 TRACE_MSG("vGetNotesInfo");
765 fail(pFile == NULL);
766 fail(pPPS == NULL && iWordVersion >= 6);
767 fail(aulBBD == NULL && tBBDLen != 0);
768 fail(aulSBD == NULL && tSBDLen != 0);
769 fail(aucHeader == NULL);
771 switch (iWordVersion) {
772 case 0:
773 vGet0NotesInfo(pFile, aucHeader);
774 break;
775 case 1:
776 case 2:
777 vGet2NotesInfo(pFile, aucHeader);
778 break;
779 case 4:
780 case 5:
781 break;
782 case 6:
783 case 7:
784 vGet6NotesInfo(pFile, pPPS->tWordDocument.ulSB,
785 aulBBD, tBBDLen, aucHeader);
786 break;
787 case 8:
788 vGet8NotesInfo(pFile, pPPS,
789 aulBBD, tBBDLen, aulSBD, tSBDLen, aucHeader);
790 break;
791 default:
792 werr(0, "Sorry, no notes information");
793 break;
795 } /* end of vGetNotesInfo */
798 * vPrepareFootnoteText - prepare the footnote text
800 void
801 vPrepareFootnoteText(FILE *pFile)
803 footnote_local_type *pCurr;
804 size_t tFootnote;
806 fail(pFile == NULL);
807 fail(pFootnoteText == NULL && tFootnoteTextLength != 0);
809 if (pFootnoteText == NULL || tFootnoteTextLength == 0) {
810 /* No information */
811 return;
814 /* Fill text and useful-ness */
815 for (tFootnote = 0; tFootnote < tFootnoteTextLength; tFootnote++) {
816 pCurr = pFootnoteText + tFootnote;
817 pCurr->bUseful = pCurr->ulCharPosStart != pCurr->ulCharPosNext;
818 if (pCurr->bUseful) {
819 pCurr->tInfo.szText = szFootnoteDecryptor(pFile,
820 pCurr->ulCharPosStart,
821 pCurr->ulCharPosNext);
822 } else {
823 pCurr->tInfo.szText = NULL;
826 } /* end of vPrepareFootnoteText */
829 * szGetFootnootText - get the text of the spefified footnote
831 const char *
832 szGetFootnootText(UINT uiFootnoteIndex)
834 if ((size_t)uiFootnoteIndex >= tFootnoteTextLength) {
835 return NULL;
837 return pFootnoteText[uiFootnoteIndex].tInfo.szText;
838 } /* end of szGetFootnootText */
841 * Get the notetype of the note at the given fileoffset
843 notetype_enum
844 eGetNotetype(ULONG ulFileOffset)
846 size_t tIndex;
848 TRACE_MSG("eGetNotetype");
850 fail(aulFootnoteList == NULL && tFootnoteListLength != 0);
851 fail(aulEndnoteList == NULL && tEndnoteListLength != 0);
853 /* Go for the easy answers first */
854 if (tFootnoteListLength == 0 && tEndnoteListLength == 0) {
855 return notetype_is_unknown;
857 if (tEndnoteListLength == 0) {
858 return notetype_is_footnote;
860 if (tFootnoteListLength == 0) {
861 return notetype_is_endnote;
863 /* No easy answer, so we search */
864 for (tIndex = 0; tIndex < tFootnoteListLength; tIndex++) {
865 if (aulFootnoteList[tIndex] == ulFileOffset) {
866 return notetype_is_footnote;
869 for (tIndex = 0; tIndex < tEndnoteListLength; tIndex++) {
870 if (aulEndnoteList[tIndex] == ulFileOffset) {
871 return notetype_is_endnote;
874 /* Not found */
875 return notetype_is_unknown;
876 } /* end of eGetNotetype */