1 //  ----------------------------------------------------------------------------
2 //  MODULE    : FileFlashPixView
3 //  LANGUAGE  : C++
4 //  CREATOR   : Philippe BOSSUT
5 //  CREAT. DATE : Thursday, April 4, 1996
6 //  DESCRIPTION :
7 //  COMMENTS  :
8 //    SCCSID      : @(#)f_fpxvw.cpp 1.5 12:24:50 08 Jul 1997
9 //  ----------------------------------------------------------------------------
10 //  Copyright (c) 1999 Digital Imaging Group, Inc.
11 //  For conditions of distribution and use, see copyright notice
12 //  in Flashpix.h
13 //  ----------------------------------------------------------------------------
14   #ifdef macintosh
15     #pragma segment FileFlashPixView
16   #endif
17 //  ----------------------------------------------------------------------------
18   #include "f_fpxvw.h"
19   #include "olecomm.h"
20 //  ----------------------------------------------------------------------------
21 
22 //  Includes
23 //  --------
24 
25   #include  <string.h>
26   #include  <stdio.h>
27 
28 #if defined(USE_LEGACY_INCLUDES)
29 #  include <fstream.h>
30 #else
31 #  include <fstream>
32    using namespace std;
33 #endif
34 
35 #ifdef macintosh
36   #include  <Errors.h>
37 #endif
38 
39 #ifndef OLECore_h
40   #include "olecore.h"
41 #endif
42 #ifndef OLEStorages_h
43   #include  "olestorg.h"
44 #endif
45 #ifndef OLEStreams_h
46   #include  "olestrm.h"
47 #endif
48 #ifndef OLEProperties_h
49   #include  "oleprop.h"
50 #endif
51 #ifndef OLEPropertySet_h
52   #include  "oleprops.h"
53 #endif
54 #ifndef OLEFiles_h
55   #include  "olefiles.h"
56 #endif
57 
58 #ifndef FlashPixUtils_h
59   #include "fpxutils.h"
60 #endif
61 
62 //  Constants
63 //  ---------
64 
65 //  Variables
66 //  ---------
67 
68 //  ----------------------------------------------------------------------------
69 //  Internal Functions
70 //  ----------------------------------------------------------------------------
71 
72 //  ----------------------------------------------------------------------------
73 //  Methods of the PFileFlashPixView class
74 //
75 //  Manage all access to the properties of a FlashPix file.
76 //  ----------------------------------------------------------------------------
77 
PFileFlashPixView(FicNom & fName,const char * theStorageName,mode_Ouverture theMode,unsigned int theVisibleOutputIndex)78 PFileFlashPixView::PFileFlashPixView (FicNom& fName, const char* theStorageName,
79                       mode_Ouverture theMode,
80                       unsigned int theVisibleOutputIndex)
81               : PImageFile(fName),
82                 readOnlyMode(FALSE)
83 {
84   CLSID clsID = ID_ImageView;
85   Boolean ok;
86 
87   // Init the root stuff
88   oleFile     = NULL;
89   parentStorage = NULL;
90   rootStorage   = NULL;
91 
92   // Init the OLE Access Flag Mode
93   switch (theMode) {
94       case mode_Lecture:
95         mode = OLE_READ_ONLY_MODE;
96         break;
97       case mode_Modification:
98         mode = OLE_READWRITE_MODE;
99         break;
100       case mode_Ecrasement:
101       case mode_Reset:
102         mode = OLE_CREATE_MODE;
103         break;
104   }
105 
106   // Create the OLE file record
107   oleFile = new OLEFile(fName,theStorageName);
108   // Open or create the root storage
109   if (mode == OLE_CREATE_MODE)
110     ok = oleFile->CreateOLEFile (clsID, &rootStorage);
111   else
112     ok = oleFile->OpenOLEFile (clsID, &rootStorage, mode);
113 
114   // CHG_VIS_OUT - set index into the Global info. Prperty Set's Visible Outputs
115   //  array to 0. Core images only have one visible output and it is accessed thru
116   //  the 0th element of this array. Use of visibleOutputIndex overrides core behavior.
117   visibleOutputIndex = theVisibleOutputIndex;
118 
119   // Init the rest or raise an error
120   if (ok)
121     Init ();
122   else
123     SignaleErreur();
124 }
125 
126 
PFileFlashPixView(OLEStorage * theOwningStorage,const char * theStorageName,mode_Ouverture theMode,unsigned int theVisibleOutputIndex)127 PFileFlashPixView::PFileFlashPixView (OLEStorage* theOwningStorage, const char* theStorageName,
128                     mode_Ouverture theMode,
129                     unsigned int theVisibleOutputIndex)
130               : PImageFile(),
131                 readOnlyMode(FALSE)
132 {
133   CLSID clsID = ID_ImageView;
134   Boolean ok = true;  // djk 052297 AI17850: initialize
135 
136   // Init the root stuff
137   oleFile     = NULL;
138   // BEGIN: djk 052297 AI17850: handle sub-storages correctly
139   ///parentStorage  = theOwningStorage;
140   parentStorage = NULL;
141   // END: djk 052297 AI17850: handle sub-storages correctly
142   rootStorage   = NULL;
143 
144   // Init the OLE Access Flag Mode
145   switch (theMode) {
146       case mode_Lecture:
147         mode = OLE_READ_ONLY_MODE;
148         break;
149       case mode_Modification:
150         mode = OLE_READWRITE_MODE;
151         break;
152       case mode_Ecrasement:
153       case mode_Reset:
154         mode = OLE_CREATE_MODE;
155         break;
156   }
157 
158   // BEGIN: djk 052297 AI17850: handle sub-storages correctly
159   if (theStorageName)
160   {
161     parentStorage = theOwningStorage;
162 
163     // Open or create the root storage
164     if (mode == OLE_CREATE_MODE)
165       ok = parentStorage->CreateStorage (clsID, theStorageName, &rootStorage);
166     else
167       ok = parentStorage->OpenStorage (clsID, theStorageName, &rootStorage, mode);
168   }
169   else
170   {
171     parentStorage = NULL;
172     rootStorage = theOwningStorage;
173   }
174   // END: djk 052297 AI17850: handle sub-storages correctly
175 
176   // CHG_VIS_OUT - set index into the Global info. Prperty Set's Visible Outputs
177   //  array to 0. Core images only have one visible output and it is accessed thru
178   //  the 0th element of this array. Use of visibleOutputIndex overrides core behavior.
179   visibleOutputIndex = theVisibleOutputIndex;
180 
181   // Init the rest or raise an error
182   if (ok)
183     Init ();
184   else
185     SignaleErreur();
186 }
187 
188 
Init()189 void PFileFlashPixView::Init ()
190 {
191   Boolean err = FALSE;
192 
193   // Set the pointers to NULL to start with...
194   globalInfoPropertySet = NULL;
195 
196   resultDescPropertySet = NULL;
197   sourceDescPropertySet = NULL;
198   operationPropertySet  = NULL;
199   transformPropertySet  = NULL;
200   summaryInfoPropertySet  = NULL;
201   extensionListPropertySet= NULL;
202 
203   // Names of the property sets
204   char summaryInfoName [33];
205   char globalInfoName [33];
206   char resultDescName [33];
207   char sourceDescName [33];
208   char operationName [33];
209   char transformName [33];
210   char extensionName [33];
211 
212   // PTCH_OBJFIX - Index/numbers used to form property names. The following are usually
213   //  correct, but are tested once the file is opened. The spec supports more complex
214   //  linkages which are determined if not in create mode.
215   sourceDescPropertyIndex = 1;
216   resultDescPropertyIndex = 2;
217   transformPropertyIndex  = 1;
218   operationPropertyIndex  = 1;
219 
220   GetSummaryInfoName(summaryInfoName);
221   GetGlobalInfoName(globalInfoName);
222   GetExtensionName(extensionName);
223 
224   // Create the basic View stuff: summary property set and the requires property sets
225   if (mode == OLE_CREATE_MODE) {
226     // CAUTION: in the reference implementation code, we ALWAYS create FPX Image View with transformation,
227     // so, some of the optionnal property sets are ALWAYS created by this code.
228 
229     // PTCH_OBJFIX - Make default names for indexed objects
230     GetImageDescName(resultDescName,resultDescPropertyIndex);
231     GetImageDescName(sourceDescName,sourceDescPropertyIndex);
232     GetTransformName(transformName,transformPropertyIndex);
233 
234     // Summary Info property set (required)
235     GUID summaryInfoGuid = ID_SummaryInfo;
236     if (rootStorage->CreatePropertySet (summaryInfoGuid, summaryInfoName, &summaryInfoPropertySet))
237       InitSummaryInfoPropertySet();
238     else
239       err = TRUE;
240 
241     // Global Info property set (required)
242     GUID globalInfoGuid = ID_GlobalInfo;
243     if ( !rootStorage->CreatePropertySet(globalInfoGuid, globalInfoName, &globalInfoPropertySet))
244       err = TRUE;
245 
246     // Source Description property set (required)
247     GUID sourceDescGuid = ID_ImageDescription;
248     if ( !rootStorage->CreatePropertySet(sourceDescGuid, sourceDescName, &sourceDescPropertySet))
249       err = TRUE;
250 
251     // Result Description property set (optionnal)
252     resultDescPropertySet = NULL;
253 
254     // Operation property set (optionnal)
255     operationPropertySet = NULL;
256 
257     // Transformation property set (optionnal)
258     transformPropertySet = NULL;
259 
260     // Extension List property set (optionnal)
261     extensionListPropertySet = NULL;
262 
263     // Create the default CompObj
264     if ( !CreateCompObj() )
265       err = TRUE;
266 
267   }
268   else {
269     // PTCH_OBJFIX - this section has been rewritten to properly determine which object is
270     //  the Source Desription object, rather than just assume it's "Data Object 000001".
271     //  See RFC_101-7_Misc_3.pdf for a description of the index/path being walked here.
272     OLEProperty* aProp;
273 
274     // Summary Info property set (required)
275     GUID summaryInfoGuid = ID_SummaryInfo;
276     if (rootStorage->OpenPropertySet (summaryInfoGuid, summaryInfoName, &summaryInfoPropertySet, mode)) {
277       if ( summaryInfoPropertySet->Revert() )
278         GetSummaryInfoPropertySet();
279       else
280         err = TRUE;
281     } else
282       err = TRUE;
283 
284     // Global Info property set (required)
285     GUID globalInfoGuid = ID_GlobalInfo;
286     if (rootStorage->OpenPropertySet(globalInfoGuid, globalInfoName, &globalInfoPropertySet, mode))
287       globalInfoPropertySet->Revert();
288     else
289       err = TRUE;
290 
291     // To find the Source and Result Description Objects and the Data Object Storage, a
292     //  series of indices stored in properties must be followed -- starting at Global Info
293     if (GetGlobalInfoProperty (PID_VisibleOutputs, &aProp)) {
294       char      objectName [33];
295 
296       // To find the Source Description Object, use the the Visible Output value in the
297       //  GlobalInfo Property as an index. Core only supports one visible output, so just
298       //  use the first value in the array.
299       // CHG_VIS_OUT - use the member 'visibleOutputIndex' to access the element
300       //  in visible outputs. This will support non-core images such as those
301       //  with multiple frames
302       const VECTOR *vector = (const VECTOR *)(*aProp);
303       if (visibleOutputIndex >= vector->cElements) {
304         visibleOutputIndex = 0;
305         err = TRUE;
306       }
307       long  dataObjectIndx = vector->prgdw[visibleOutputIndex];
308 
309       // Use the Visible Output index to make the name of a Description Data Object. This is
310       //  usually the Source Description Object, but it may not be.
311       OLEPropertySet  *imgPropSet;
312       GetImageDescName (objectName, dataObjectIndx);
313       GUID sourceDescGuid = ID_ImageDescription;
314 
315       if (rootStorage->OpenPropertySet (sourceDescGuid, objectName, &imgPropSet, mode)) {
316         imgPropSet->Revert();
317 
318         // If the 'creator' is 0, then this is the Source Description Object. If not,
319         //  then creator is the index of the Transform Object and this object is the
320         //  Result Description Object.
321         if (imgPropSet->GetProperty (PID_Creator, &aProp)) {
322           int32_t  creatorIndex = (int32_t)(*aProp);
323 
324           if (creatorIndex == 0) {
325             sourceDescPropertySet = imgPropSet;
326             sourceDescPropertyIndex = dataObjectIndx;
327 
328             // CHG_OBJ_FIX - set the transform and operation object indices to 0,
329             //    since there are none for this image. This pervents a future
330             //    problem where multiple images may exist and these objects
331             //    do exist, but they're not for this particular image.
332             transformPropertyIndex  = 0;
333             operationPropertyIndex  = 0;
334           }
335           else {
336             // Since there is a creator index, the object we opened is the
337             //  result. The Source Description Objects index is found by using
338             //  the creator as an index to the Transform Object that creates
339             //  final image. The Transforms 'Input Data Object' will then
340             //  indicate which Description object is the Source Dscr Object.
341             // Core only supports one value in the Input Data Object array.
342 
343             resultDescPropertySet = imgPropSet;
344             resultDescPropertyIndex = dataObjectIndx;
345 
346             GetTransformName (objectName, creatorIndex);
347             GUID transformGuid = ID_Transform;
348 
349             if (rootStorage->OpenPropertySet (transformGuid, objectName,
350                                               &transformPropertySet, mode)) {
351               transformPropertySet->Revert();
352 
353               if (GetTransformProperty (PID_InputObjectList, &aProp)) {
354                 FPXLongArray  inputDataList = (FPXLongArray)(*aProp);
355                 sourceDescPropertyIndex = inputDataList.ptr[0];
356                 transformPropertyIndex  = creatorIndex;
357 
358                 if (GetTransformProperty (PID_OperationNumber, &aProp))
359                   operationPropertyIndex  = (int32_t)(*aProp);
360               }
361               else  err = TRUE;     // GetProperty failed
362             }
363             else  err = TRUE;       // OpenPropertySet failed
364           }
365         }
366         else  err = TRUE;           // GetSourceDescProperty failed
367       }
368       else  err = TRUE;             // OpenPropertySet failed
369     }
370     else  err = TRUE;               // GetGlobalInfoProperty failed
371 
372 
373     // Source Description property set (required)
374     // PTCH_OBJFIX - Don't need to open this if it was done earlier.
375     if (sourceDescPropertySet == NULL) {
376       GetImageDescName(sourceDescName,sourceDescPropertyIndex);
377       GUID sourceDescGuid = ID_ImageDescription;
378       if (rootStorage->OpenPropertySet(sourceDescGuid, sourceDescName, &sourceDescPropertySet, mode))
379         sourceDescPropertySet->Revert();
380       else
381         err = TRUE;
382     }
383 
384     // Result Description property set (optional)
385     // PTCH_OBJFIX - Don't need to open this if it was done earlier.
386     if (resultDescPropertySet == NULL) {
387       GetImageDescName(resultDescName,resultDescPropertyIndex);
388       GUID resultDescGuid = ID_ImageDescription;
389       if (rootStorage->OpenPropertySet(resultDescGuid, resultDescName, &resultDescPropertySet, mode))
390         resultDescPropertySet->Revert();
391       else
392         resultDescPropertySet = NULL;
393     }
394 
395     // Operation property set (optional)
396     GetOperationName(operationName,operationPropertyIndex);
397     GUID operationGuid = ID_Operation;
398     if (rootStorage->OpenPropertySet(operationGuid, operationName, &operationPropertySet, mode))
399       operationPropertySet->Revert();
400     else
401       operationPropertySet = NULL;
402 
403     // Transformation property set (optional)
404     // PTCH_OBJFIX - Don't need to open this if it was done earlier.
405     if (transformPropertySet == NULL) {
406       GetTransformName(transformName,transformPropertyIndex);
407       GUID transformGuid = ID_Transform;
408       if (rootStorage->OpenPropertySet(transformGuid, transformName, &transformPropertySet, mode))
409         transformPropertySet->Revert();
410       else
411         transformPropertySet = NULL;
412     }
413 
414     // Extension List property set (optional)
415     GUID extensionGuid = ID_Extension;
416     if (rootStorage->OpenPropertySet(extensionGuid, extensionName, &extensionListPropertySet,
417                                      mode))
418       extensionListPropertySet->Revert();
419     else
420       extensionListPropertySet = NULL;
421   }
422 
423   // Check if an error occured during the init
424   if (err)
425     SignaleErreur();
426 }
427 
428 
getStatus(void)429 FPXStatus PFileFlashPixView::getStatus(void)
430 {
431   FPXStatus status;
432   status = oleFile->getFPXStatus();
433   return status;
434 }
435 
436 
~PFileFlashPixView()437 PFileFlashPixView::~PFileFlashPixView ()
438 {
439   // CAUTION: Elements have to be deleted in the reverse order of their creation...
440 
441   // Commit() makes sure that everything has been written on the disk (flush
442   // all ole buffers for the elements)
443   if (mode != OLE_READ_ONLY_MODE)
444     Commit();
445 
446   // Delete an element releases the OLE object.
447   if (globalInfoPropertySet) {
448     delete globalInfoPropertySet;
449     globalInfoPropertySet = NULL;
450   }
451   if (resultDescPropertySet) {
452     delete resultDescPropertySet;
453     resultDescPropertySet = NULL;
454   }
455   if (sourceDescPropertySet) {
456     delete sourceDescPropertySet;
457     sourceDescPropertySet = NULL;
458   }
459   if (operationPropertySet) {
460     delete operationPropertySet;
461     operationPropertySet = NULL;
462   }
463   if (transformPropertySet) {
464     delete transformPropertySet;
465     transformPropertySet = NULL;
466   }
467   if (summaryInfoPropertySet) {
468     delete summaryInfoPropertySet;
469     summaryInfoPropertySet = NULL;
470   }
471   if (extensionListPropertySet) {
472     delete extensionListPropertySet;
473     extensionListPropertySet = NULL;
474   }
475 
476   // At last, release the file. CAUTION: the rootStorage is release by the file...
477   // NOTE: The above comment has been changed, the rootStorage has to be released separately.
478   // BEGIN: djk 052397 AI17850
479   // Always release anything referenced by FPX! The root storage refers to the FPX root,
480   // which may be anywhere within a DocFile.
481   delete rootStorage;
482 
483   if (oleFile) {
484   // END: djk 052397 AI17850
485     delete oleFile;
486   }
487 }
488 
489 
CreateStorage(CLSID & classID,const char * name,OLEStorage ** res)490 Boolean PFileFlashPixView::CreateStorage(CLSID& classID, const char * name, OLEStorage ** res)
491 {
492   if (rootStorage)
493     return rootStorage->CreateStorage(classID, name, res);
494   else
495     return FALSE;
496 }
497 
498 
OpenStorage(CLSID & classID,const char * name,OLEStorage ** res)499 Boolean PFileFlashPixView::OpenStorage(CLSID& classID, const char * name, OLEStorage ** res)
500 {
501   if (rootStorage)
502     return rootStorage->OpenStorage(classID, name, res);
503   else
504     return FALSE;
505 }
506 
507 
GetError()508 FPXStatus PFileFlashPixView::GetError()
509 {
510   return Erreur();
511 }
512 
513 
Erreur() const514 FPXStatus PFileFlashPixView::Erreur() const
515 {
516   long    error = 0;
517   FPXStatus status = FPX_OK;
518 
519   if (error == noErr) {
520     if (summaryInfoPropertySet)
521       error = summaryInfoPropertySet->Error();
522     else
523       error = -1;
524   }
525 
526   if (error == noErr) {
527     if (globalInfoPropertySet)
528       error = globalInfoPropertySet->Error();
529     else
530       error = -1;
531   }
532 
533   if (error == noErr) {
534     if (resultDescPropertySet)
535       error = resultDescPropertySet->Error();
536     else
537       error = -1;
538   }
539 
540   if (error == noErr) {
541     if (sourceDescPropertySet)
542       error = sourceDescPropertySet->Error();
543     else
544       error = -1;
545   }
546 
547   if (error == noErr) {
548     if (operationPropertySet)
549       error = operationPropertySet->Error();
550     else
551       error = -1;
552   }
553 
554   if (error == noErr) {
555     if (transformPropertySet)
556       error = transformPropertySet->Error();
557     else
558       error = -1;
559   }
560 
561   if (error == noErr) {
562     if (extensionListPropertySet)
563       error = extensionListPropertySet->Error();
564     else
565       error = -1;
566   }
567 
568   if (error) {                  // If there is an error durng property set access
569     status = oleFile->getFPXStatus();     //  get the most recent OLE file error
570     if (status == FPX_OK)           // If there was no error saved in OLE, then
571       status = FPX_FILE_READ_ERROR;     //  make a wild guess that it's a read error
572   }
573   return status;
574 }
575 
576 
Commit()577 Boolean PFileFlashPixView::Commit()
578 {
579   Boolean ok = TRUE;
580   if (summaryInfoPropertySet)
581     ok &= summaryInfoPropertySet->Commit();
582   if (globalInfoPropertySet)
583     ok &= globalInfoPropertySet->Commit();
584   if (resultDescPropertySet)
585     ok &= resultDescPropertySet->Commit();
586   if (sourceDescPropertySet)
587     ok &= sourceDescPropertySet->Commit();
588   if (operationPropertySet)
589     ok &= operationPropertySet->Commit();
590   if (transformPropertySet)
591     ok &= transformPropertySet->Commit();
592   if (extensionListPropertySet)
593     ok &= extensionListPropertySet->Commit();
594   if (rootStorage)
595     ok &= rootStorage->Commit();
596   return ok;
597 }
598 
599 // This should probably go somewhere else
600 // FIXME:
601 #if   defined(_UNIX)
602 
603 #define USERCLASSTYPE_APPNAME 0
604 
OleRegGetUserType(REFCLSID clsid,DWORD whatever,LPOLESTR FAR * pszUserType)605 HRESULT OleRegGetUserType(REFCLSID clsid, DWORD whatever, LPOLESTR FAR* pszUserType)
606 {
607     if (*pszUserType == NULL) {
608         *pszUserType = new OLECHAR[512];
609     }
610 
611     const OLECHAR *src=OLESTR("Flashpix Toolkit Application");
612     OLECHAR *dest=*pszUserType;
613     while(*src) *dest++=*src++;
614     *dest=(OLECHAR)0;
615 
616     return S_OK;
617 }
618 
StringFromCLSID(REFCLSID clsid,LPOLESTR FAR * lplpsz)619 HRESULT StringFromCLSID(REFCLSID clsid, LPOLESTR FAR* lplpsz)
620 {
621 
622     *lplpsz = new OLECHAR[512];
623     char lpsz[512];
624 
625     WORD  Data4 = clsid.Data4[0]<<8 & clsid.Data4[1];
626     WORD  Data5 = clsid.Data4[2]<<8 & clsid.Data4[3];
627     DWORD Data6 = clsid.Data4[4]<<24 & clsid.Data4[5]<<16 & clsid.Data4[6]<<8 & clsid.Data4[7];
628 
629     sprintf(lpsz, "{%08x-%04x-%04x-%04x-%04x%08x}", (unsigned int) clsid.Data1, clsid.Data2,
630             clsid.Data3, Data4, Data5, (unsigned int) Data6);
631     INIT_OLESTR(*lplpsz, lpsz);
632     return S_OK;
633 }
634 
635 #endif
636 
637 // Create CompObj in root storage
CreateCompObj()638 Boolean PFileFlashPixView::CreateCompObj()
639 {
640   OLEStream * curCompObj;
641 
642   if (rootStorage->CreateStream("\1CompObj", &curCompObj)) {
643 
644     // Write the header
645     DWORD temp;
646     temp = 0xfffe0001;
647     curCompObj->WriteVT_I4(&temp);
648 
649     temp = 0x00000a03;
650     curCompObj->WriteVT_I4(&temp);
651 
652     temp = (DWORD) -1;
653     curCompObj->WriteVT_I4(&temp);
654 
655     CLSID clsID = ID_ImageView;
656     curCompObj->WriteVT_CLSID(&clsID);
657 
658     // Get new user type name; if error, set to NULL string
659     OLECHAR chZero = 0;
660     LPOLESTR lpszNew = NULL;
661     if (OleRegGetUserType(clsID, USERCLASSTYPE_APPNAME, &lpszNew) != S_OK)
662     {
663       lpszNew = new OLECHAR[1];
664       lpszNew[0]=chZero;
665     }
666 
667 #if defined(macintosh) || defined(_UNIX)
668     curCompObj->WriteVT_LPSTR_NoPad(lpszNew);
669 #elif _WINDOWS
670     char str[1024];
671     WideCharToMultiByte(CP_ACP, 0, lpszNew, -1, str, 128, NULL, NULL);
672     curCompObj->WriteVT_LPSTR_NoPad(str);
673 #endif
674 
675     // Get and write clsID string
676     LPOLESTR FAR clsIDStr;
677     StringFromCLSID(clsID, &clsIDStr);
678 #if defined(macintosh) || defined(_UNIX)
679     curCompObj->WriteVT_LPSTR_NoPad(clsIDStr);
680 #elif _WINDOWS
681     WideCharToMultiByte(CP_ACP, 0, clsIDStr, -1, str, 128, NULL, NULL);
682     curCompObj->WriteVT_LPSTR_NoPad(str);
683 #endif
684 
685     // Write prog id ( for now just write length = 0 )
686 #if defined(macintosh) || defined(_UNIX)
687     curCompObj->WriteVT_LPSTR_NoPad(&chZero);
688 #elif _WINDOWS
689     char progID = 0;
690     curCompObj->WriteVT_LPSTR_NoPad(&progID);
691 #endif
692 
693     // Write magic number
694     temp = 0x71B239F4;
695     curCompObj->WriteVT_I4(&temp);
696 
697     // Write unicode user type ( for now just write length = 0 )
698 #if defined(macintosh) || defined(_UNIX)
699     curCompObj->WriteVT_LPWSTR_NoPad(MultiByteToWideChar(lpszNew));
700 #elif _WINDOWS
701     curCompObj->WriteVT_LPWSTR_NoPad(lpszNew);
702 #endif
703 
704     // Write unicode clipboard format
705 #if defined(macintosh) || defined(_UNIX)
706     curCompObj->WriteVT_LPWSTR_NoPad(MultiByteToWideChar(&chZero));
707 #elif _WINDOWS
708     curCompObj->WriteVT_LPWSTR_NoPad(&chZero);
709 #endif
710 
711     // Write unicode prog id ( for now just write length = 0 )
712 #if defined(macintosh) || defined(_UNIX)
713     curCompObj->WriteVT_LPWSTR_NoPad(MultiByteToWideChar(&chZero));
714 #elif _WINDOWS
715     curCompObj->WriteVT_LPWSTR_NoPad(&chZero);
716 #endif
717 
718     // We may need to call some other memory methods.
719     delete[] lpszNew;  // FIXME: Crashes here with assertion error.
720   }
721   else
722     return FALSE;
723 
724   return TRUE;
725 }
726 
727 
728 // Read CompObj in root storage
ReadCompObj(char ** ppUserType,char ** ppClipFormat)729 Boolean PFileFlashPixView::ReadCompObj(char **ppUserType, char **ppClipFormat)
730 {
731   OLEStream * curCompObj;
732 
733   if (rootStorage)
734     if ( rootStorage->OpenStream("\1CompObj", &curCompObj) ) {
735       curCompObj->Seek(sizeof(COMPOBJHEADER));
736 
737       // Read user type string
738       curCompObj->ReadVT_LPSTR_NoPad(ppUserType);
739 
740       // Read clipboard format string
741       curCompObj->ReadVT_LPSTR_NoPad(ppClipFormat);
742     }
743     else
744       return false;
745   else
746     return false;
747 
748   return true;
749 }
750 
751 // Write CompObj in root storage
WriteCompObj(char * pUserType,char * pClipFormat)752 Boolean PFileFlashPixView::WriteCompObj(char *pUserType, char *pClipFormat)
753 {
754   OLEStream * curCompObj;
755 
756   if (rootStorage)
757     if ( rootStorage->OpenStream("\1CompObj", &curCompObj) ) {
758       curCompObj->Seek(sizeof(COMPOBJHEADER));
759 
760       // Write user type string
761       curCompObj->WriteVT_LPSTR_NoPad(pUserType);
762 
763       // Write clipboard format string
764       curCompObj->WriteVT_LPSTR_NoPad(pClipFormat);
765     }
766     else
767         return false;
768   else
769     return false;
770 
771   return true;
772 }
773 
774 
775 // Get property in summary info property set
GetSummaryInfoProperty(DWORD pID,OLEProperty ** res)776 Boolean PFileFlashPixView::GetSummaryInfoProperty (DWORD pID, OLEProperty ** res)
777 {
778   Boolean ok = TRUE;
779 
780   // If absent, there is an error
781   if (summaryInfoPropertySet == NULL)
782     ok = FALSE;
783 
784   // Get the property
785   if (ok)
786     ok = summaryInfoPropertySet->GetProperty(pID, res);
787 
788   return ok;
789 }
790 
791 // Set property in summary info property set
SetSummaryInfoProperty(DWORD pID,DWORD propType,OLEProperty ** res)792 Boolean PFileFlashPixView::SetSummaryInfoProperty (DWORD pID, DWORD propType, OLEProperty ** res)
793 {
794   Boolean ok = TRUE;
795 
796   // If absent, there is an error
797   if (summaryInfoPropertySet == NULL)
798     ok = FALSE;
799 
800   // Get the property
801   if (ok)
802     ok = summaryInfoPropertySet->NewProperty(pID, propType, res);
803 
804   return ok;
805 }
806 
807 
808 // Get property in global info property set
GetGlobalInfoProperty(DWORD pID,OLEProperty ** res)809 Boolean PFileFlashPixView::GetGlobalInfoProperty (DWORD pID, OLEProperty ** res)
810 {
811   Boolean ok = TRUE;
812 
813   // If absent, there is an error
814   if (globalInfoPropertySet == NULL)
815     ok = FALSE;
816 
817   // Get the property
818   if (ok)
819     ok = globalInfoPropertySet->GetProperty(pID, res);
820 
821   return ok;
822 }
823 
824 
825 // Set property in global info property set
SetGlobalInfoProperty(DWORD pID,DWORD propType,OLEProperty ** res)826 Boolean PFileFlashPixView::SetGlobalInfoProperty (DWORD pID, DWORD propType, OLEProperty ** res)
827 {
828   Boolean ok = TRUE;
829 
830   // If absent, there is an error
831   if (globalInfoPropertySet == NULL)
832     ok = FALSE;
833 
834   // Get the property
835   if (ok)
836     ok = globalInfoPropertySet->NewProperty(pID, propType, res);
837 
838   return ok;
839 }
840 
841 
842 // Get property in result description property set
GetResultDescProperty(DWORD pID,OLEProperty ** res)843 Boolean PFileFlashPixView::GetResultDescProperty (DWORD pID, OLEProperty ** res)
844 {
845   Boolean ok = TRUE;
846 
847   // If absent, there is an error
848   if (resultDescPropertySet == NULL)
849     ok = FALSE;
850 
851   // Get the property
852   if (ok)
853     ok = resultDescPropertySet->GetProperty(pID, res);
854 
855   return ok;
856 }
857 
858 
859 // Set property in result description property set
SetResultDescProperty(DWORD pID,DWORD propType,OLEProperty ** res)860 Boolean PFileFlashPixView::SetResultDescProperty (DWORD pID, DWORD propType, OLEProperty ** res)
861 {
862   Boolean ok = TRUE;
863   char resultDescName [33];
864   GetImageDescName(resultDescName,2);   // Baseline limitation. See VIII.2.1.
865 
866   // If absent, the Result Description property set has to be created
867   if (resultDescPropertySet == NULL) {
868     GUID resultDescGuid = ID_ImageDescription;
869     if ( !rootStorage->CreatePropertySet(resultDescGuid, resultDescName, &resultDescPropertySet))
870       ok = FALSE;
871   }
872 
873   // Add the property to the section
874   if (ok)
875     ok = resultDescPropertySet->NewProperty(pID, propType, res);
876 
877   return ok;
878 }
879 
880 
881 // Get property in source description property set
GetSourceDescProperty(DWORD pID,OLEProperty ** res)882 Boolean PFileFlashPixView::GetSourceDescProperty (DWORD pID, OLEProperty ** res)
883 {
884   Boolean ok = TRUE;
885 
886   // If absent, there is an error
887   if (sourceDescPropertySet == NULL)
888     ok = FALSE;
889 
890   // Get the property
891   if (ok)
892     ok = sourceDescPropertySet->GetProperty(pID, res);
893 
894   return ok;
895 }
896 
897 
898 // Set property in source description property set
SetSourceDescProperty(DWORD pID,DWORD propType,OLEProperty ** res)899 Boolean PFileFlashPixView::SetSourceDescProperty (DWORD pID, DWORD propType, OLEProperty ** res)
900 {
901   Boolean ok = TRUE;
902   char sourceDescName [33];
903   GetImageDescName(sourceDescName,1);   // Baseline limitation. See VIII.2.1.
904 
905   // If absent, the Source Description property set has to be created
906   if (sourceDescPropertySet == NULL) {
907     GUID sourceDescGuid = ID_ImageDescription;
908     if ( !rootStorage->CreatePropertySet(sourceDescGuid, sourceDescName, &sourceDescPropertySet))
909       ok = FALSE;
910   }
911 
912   // Add the property to the section
913   if (ok)
914     ok = sourceDescPropertySet->NewProperty(pID, propType, res);
915 
916   return ok;
917 }
918 
919 
920 // Get property in operation property set
GetOperationProperty(DWORD pID,OLEProperty ** res)921 Boolean PFileFlashPixView::GetOperationProperty (DWORD pID, OLEProperty ** res)
922 {
923   Boolean ok = TRUE;
924 
925   // If absent, there is an error
926   if (operationPropertySet == NULL)
927     ok = FALSE;
928 
929   // Get the property
930   if (ok)
931     ok = operationPropertySet->GetProperty(pID, res);
932 
933   return ok;
934 }
935 
936 
937 // Set property in operation property set
SetOperationProperty(DWORD pID,DWORD propType,OLEProperty ** res)938 Boolean PFileFlashPixView::SetOperationProperty (DWORD pID, DWORD propType, OLEProperty ** res)
939 {
940   Boolean ok = TRUE;
941   char operationName [33];
942   GetOperationName(operationName,1);    // Baseline limitation. See VIII.2.1.
943 
944   // If absent, the Operation property set has to be created
945   if (operationPropertySet == NULL) {
946     GUID operationGuid = ID_Operation;
947     if ( !rootStorage->CreatePropertySet(operationGuid, operationName, &operationPropertySet))
948       ok = FALSE;
949   }
950 
951   // Add the property to the section
952   if (ok)
953     ok = operationPropertySet->NewProperty(pID, propType, res);
954 
955   return ok;
956 }
957 
958 // Get property in transform property set
GetTransformProperty(DWORD pID,OLEProperty ** res)959 Boolean PFileFlashPixView::GetTransformProperty (DWORD pID, OLEProperty ** res)
960 {
961   Boolean ok = TRUE;
962 
963   // If absent, there is an error
964   if (transformPropertySet == NULL)
965     ok = FALSE;
966 
967   // Get the property
968   if (ok)
969     ok = transformPropertySet->GetProperty(pID, res);
970 
971   return ok;
972 }
973 
974 
975 // Set property in transform property set
SetTransformProperty(DWORD pID,DWORD propType,OLEProperty ** res)976 Boolean PFileFlashPixView::SetTransformProperty (DWORD pID, DWORD propType, OLEProperty ** res)
977 {
978   Boolean ok = TRUE;
979   char transformName [33];
980   GetTransformName(transformName,1);    // Baseline limitation. See VIII.2.1.
981 
982   // If absent, the Transformation property set has to be created
983   if (transformPropertySet == NULL) {
984     GUID transformGuid = ID_Transform;
985     if ( !rootStorage->CreatePropertySet(transformGuid, transformName, &transformPropertySet))
986       ok = FALSE;
987   }
988 
989   // Add the property to the section
990   if (ok)
991     ok = transformPropertySet->NewProperty(pID, propType, res);
992 
993   return ok;
994 }
995 
996 // Get property in extension property set
GetExtensionProperty(DWORD pID,OLEProperty ** res)997 Boolean PFileFlashPixView::GetExtensionProperty (DWORD pID, OLEProperty ** res)
998 {
999   Boolean ok = TRUE;
1000 
1001   // If absent, there is an error
1002   if (extensionListPropertySet == NULL)
1003     ok = FALSE;
1004 
1005   // Get the property
1006   if (ok)
1007     ok = extensionListPropertySet->GetProperty(pID, res);
1008 
1009   return ok;
1010 }
1011 
1012 
1013 // Set property in extension property set
SetExtensionProperty(DWORD pID,DWORD propType,OLEProperty ** res)1014 Boolean PFileFlashPixView::SetExtensionProperty (DWORD pID, DWORD propType, OLEProperty ** res)
1015 {
1016   Boolean ok = TRUE;
1017   char extensionName [33];
1018   GetExtensionName(extensionName);
1019 
1020   // If absent, the Extension property set has to be created
1021   if (extensionListPropertySet == NULL) {
1022     GUID extensionGuid = ID_Extension;
1023     if ( !rootStorage->CreatePropertySet(extensionGuid, extensionName, &extensionListPropertySet))
1024       ok = FALSE;
1025   }
1026 
1027   // Add the property to the section
1028   if (ok)
1029     ok = extensionListPropertySet->NewProperty(pID, propType, res);
1030 
1031   return ok;
1032 }
1033 
1034 
1035 // Get extension number for specified extension name
GetExtensionNumber(LPWSTR theExtensionName,short * extNumber)1036 Boolean PFileFlashPixView::GetExtensionNumber (LPWSTR theExtensionName, short *extNumber)
1037 {
1038   char      extensionName [33];
1039   OLEProperty*  aProp;
1040   FPXWideStr    targetWStr;
1041 
1042   // Make a wide string descriptor for the ext name we're looking for
1043   targetWStr.length = FPX_LPWSTRlen( theExtensionName);
1044   targetWStr.ptr = theExtensionName;
1045 
1046   GetExtensionName(extensionName);
1047 
1048   // If absent, the extension property set has to be created
1049   if (extensionListPropertySet == NULL) {
1050     GUID extensionGuid = ID_Extension;
1051     if ( !rootStorage->CreatePropertySet(extensionGuid, extensionName, &extensionListPropertySet))
1052       return FALSE;
1053   }
1054 
1055   // If extension list array does't exist in Extension property set, create one with no entry
1056   if ( !GetExtensionProperty (PID_UsedExtensionNumber, &aProp) ) {
1057 
1058     fpxExtensionList.length = 0;
1059     fpxExtensionList.ptr  = NULL;
1060     if ( SetExtensionProperty (PID_UsedExtensionNumber, TYP_UsedExtensionNumber, &aProp) )
1061       *aProp = fpxExtensionList;
1062   }
1063   else {
1064     fpxExtensionList = (FPXShortArray)(*aProp);
1065 
1066     // Compare the extension name with each of ones in extension list array
1067     for ( long i = 0; i < (long) fpxExtensionList.length; i++ )
1068       if ( GetExtensionProperty (PID_ExtensionName(fpxExtensionList.ptr[i]), &aProp) ) {
1069 
1070         // Get extension name stored in property
1071         LPWSTR    extName = *aProp;
1072         FPXWideStr  thisWStr;
1073 
1074         // Make a wide string descriptor for ext prop in file
1075         thisWStr.length = FPX_LPWSTRlen( extName);
1076         thisWStr.ptr = extName;
1077 
1078         // Compare the name with specified one
1079         if ( !FPX_WideStrcmp(&targetWStr, &thisWStr) ) {
1080 
1081           // Return the extension number in extension list array
1082           *extNumber = fpxExtensionList.ptr[i];
1083           return TRUE;
1084         }
1085       }
1086   }
1087 
1088   // Since no extension number is found, return false
1089   return FALSE;
1090 }
1091 
1092 
1093 // Set a new extension number
SetExtensionNumber(short * extNumber)1094 Boolean PFileFlashPixView::SetExtensionNumber (short *extNumber)
1095 {
1096   char extensionName [33];
1097   OLEProperty* aProp;
1098 
1099   GetExtensionName(extensionName);
1100 
1101   // If absent, the Extension property set has to be created
1102   if (extensionListPropertySet == NULL) {
1103     GUID extensionGuid = ID_Extension;
1104     if ( !rootStorage->CreatePropertySet(extensionGuid, extensionName, &extensionListPropertySet))
1105       return FALSE;
1106   }
1107 
1108   // If extension list array does't exist in Extension property set, create one
1109   if ( !GetExtensionProperty (PID_UsedExtensionNumber, &aProp) ) {
1110 
1111     fpxExtensionList.length = 0;
1112     fpxExtensionList.ptr  = NULL;
1113 
1114     // Reallocate the extension list array and array count ( currently the extension is same as array index)
1115     if ( Renew((short **)&fpxExtensionList.ptr, 0, (short)++fpxExtensionList.length) )
1116       if ( SetExtensionProperty (PID_UsedExtensionNumber, TYP_UsedExtensionNumber, &aProp) ) {
1117         *aProp = fpxExtensionList;
1118         *extNumber = 0;
1119       }
1120       else
1121         return FALSE;
1122     else
1123       return FALSE;
1124   }
1125   else {
1126 
1127     // Reallocate the extension list array and array count ( currently the extension is same as array index)
1128     if ( Renew((short **)&fpxExtensionList.ptr, (short) fpxExtensionList.length, (short) fpxExtensionList.length + 1) )
1129       if ( SetExtensionProperty (PID_UsedExtensionNumber, TYP_UsedExtensionNumber, &aProp) ) {
1130 
1131         // Get the new extension number
1132         *extNumber = fpxExtensionList.ptr[fpxExtensionList.length];
1133 
1134         // Set the new extension list to property set
1135         ++fpxExtensionList.length;
1136         *aProp = fpxExtensionList;
1137       }
1138       else
1139         return FALSE;
1140     else
1141       return FALSE;
1142   }
1143 
1144   return TRUE;
1145 }
1146 
1147 // Reallocate the array and keep the content in old array
Renew(short ** ppa,short newEntry,short newSize)1148 Boolean PFileFlashPixView::Renew( short **ppa, short newEntry, short newSize)
1149 {
1150   // If array already exist, delete it first
1151   if ( *ppa )
1152   {
1153     // Allocate a temporary array with new size
1154     short*  temp = new short [newSize];
1155     if (!temp)    return FALSE;
1156 
1157     // Transfer the data in old array into new one
1158     for ( long i = 0; i< newSize-1; i++ )
1159       temp[i] = *ppa[i];
1160 
1161     // Save the new number in last entry of array
1162     temp[newSize - 1] = newEntry;
1163 
1164     // Delete the old array and assign the temporary one
1165     delete *ppa;
1166     *ppa = temp;
1167   }
1168   else
1169   {
1170     // Allocate a new array with new size
1171     *ppa = new short [newSize];
1172     if (!*ppa)    return FALSE;
1173 
1174     // Save the new number in last entry of array
1175     *ppa[newSize - 1] = newEntry;
1176   }
1177 
1178   return TRUE;
1179 }
1180 
1181 
1182 // Initialize the summary info property set
InitSummaryInfoPropertySet()1183 Boolean  PFileFlashPixView::InitSummaryInfoPropertySet()
1184 {
1185   OLEProperty* aProp;
1186   Boolean err = FALSE;
1187   FILETIME ft;
1188 
1189   if (summaryInfoPropertySet->GetProperty (PROPERTYIDONE, &aProp))  // Change the code page to 1252
1190     *aProp = (short)(1252);
1191   else if (summaryInfoPropertySet->NewProperty (PROPERTYIDONE, VT_I2, &aProp))
1192     *aProp = (short)(1252);
1193   else
1194     err = TRUE;
1195 
1196   if(summaryInfoPropertySet->NewProperty (long(10), VT_FILETIME, &aProp)) // edit time
1197   {
1198     FPXUpdateTime((FPXfiletime *)&ft);
1199     *aProp = FILETIME(ft);
1200   }
1201   else err = TRUE;
1202 
1203   if(summaryInfoPropertySet->NewProperty (long(11), VT_FILETIME, &aProp)) // last printed
1204   {
1205     FPXUpdateTime((FPXfiletime *)&ft);
1206     *aProp = FILETIME(ft);
1207   }
1208   else err = TRUE;
1209 
1210   if(summaryInfoPropertySet->NewProperty (long(12), VT_FILETIME, &aProp)) // create date and time
1211   {
1212     FPXUpdateTime((FPXfiletime *)&ft);
1213     *aProp = FILETIME(ft);
1214   }
1215   else err = TRUE;
1216 
1217   if(summaryInfoPropertySet->NewProperty (long(13), VT_FILETIME, &aProp)) // last save date and time
1218   {
1219     FPXUpdateTime((FPXfiletime *)&ft);
1220     *aProp = FILETIME(ft);
1221   }
1222   else err = TRUE;
1223 
1224   if(summaryInfoPropertySet->NewProperty (long(14), VT_I4, &aProp))   // page count
1225     *aProp = int32_t(0);
1226   else err = TRUE;
1227 
1228   if(summaryInfoPropertySet->NewProperty (long(15), VT_I4, &aProp))   // word count
1229     *aProp = int32_t(0);
1230   else err = TRUE;
1231 
1232   if(summaryInfoPropertySet->NewProperty (long(16), VT_I4, &aProp))   // char count
1233     *aProp = int32_t(0);
1234   else err = TRUE;
1235 
1236   if (!err)
1237     return summaryInfoPropertySet->Commit();
1238   else
1239     return FALSE;
1240 }
1241 
1242 
GetSummaryInfoPropertySet()1243 Boolean  PFileFlashPixView::GetSummaryInfoPropertySet()
1244 {
1245   OLEProperty*  aProp;
1246   Boolean     err = FALSE;
1247   FILETIME    ft;
1248 
1249   if (summaryInfoPropertySet->GetProperty (long(10), &aProp))   // edit time
1250     ft = FILETIME(*aProp);
1251   else err = TRUE;
1252 
1253   if (summaryInfoPropertySet->GetProperty (long(11), &aProp))   // last printed
1254     ft = FILETIME(*aProp);
1255   else err = TRUE;
1256 
1257   if (summaryInfoPropertySet->GetProperty (long(12), &aProp))   // create date and time
1258     ft = FILETIME(*aProp);
1259   else err = TRUE;
1260 
1261   if (summaryInfoPropertySet->GetProperty (long(13), &aProp))   // last save date and time
1262     ft = FILETIME(*aProp);
1263   else err = TRUE;
1264 
1265   return !err;
1266 }
1267 
1268 //  ----------------------------------------------------------------------------
1269 //  External Functions
1270 //  ----------------------------------------------------------------------------
1271 
1272 
1273 
1274 //  - EOF ----------------------------------------------------------------------
1275