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