1 /* $XConsortium: ilefs.c /main/3 1995/10/23 15:47:01 rswiston $ */
2 /**---------------------------------------------------------------------
4 *** (c)Copyright 1992 Hewlett-Packard Co.
6 *** RESTRICTED RIGHTS LEGEND
7 *** Use, duplication, or disclosure by the U.S. Government is subject to
8 *** restrictions as set forth in sub-paragraph (c)(1)(ii) of the Rights in
9 *** Technical Data and Computer Software clause in DFARS 252.227-7013.
10 *** Hewlett-Packard Company
11 *** 3000 Hanover Street
12 *** Palo Alto, CA 94304 U.S.A.
13 *** Rights for non-DOD U.S. Government Departments and Agencies are as set
14 *** forth in FAR 52.227-19(c)(1,2).
16 ***-------------------------------------------------------------------*/
21 #include "ilcontext.h"
23 #include "ilpipeint.h"
26 /* Beginning of file and file type recs - separate so list heads are smaller. */
28 ilObjectRec o; /* std header: MUST BE FIRST */
29 struct _ilEFSFileTypeRec *pNext, *pPrev; /* forward / back ptrs */
30 } ilEFSHeaderRec, *ilEFSHeaderPtr;
32 /* Private definition of an ilEFSFileType: an IL object. */
33 typedef struct _ilEFSFileTypeRec {
34 ilEFSHeaderRec h; /* header: MUST BE FIRST */
35 ilEFSFileTypeInfo info; /* public file type info */
36 } ilEFSFileTypeRec, *ilEFSFileTypePtr;
39 /* EFS private data, hung off of context.pAlloc[IL_CONTEXT_ALLOC_EFS]. */
41 ilEFSHeaderRec fileTypeHead; /* list of active file types */
42 ilEFSHeaderRec replacedFileTypeHead; /* list of replaced file types */
43 } ilEFSPrivateRec, *ilEFSPrivatePtr;
46 /* Private definition of an ilEFSFile: an IL object. */
48 ilObjectRec o; /* std header: MUST BE FIRST */
49 ilEFSFileInfo info; /* public file type info */
50 ilEFSFileTypePtr pFileType; /* convenience: ptr to file type */
51 } ilEFSFileRec, *ilEFSFilePtr;
54 /* Add _pFileType in front of element _pNextFileType */
55 #define LINK_FILE_TYPE(_pFileType, _pNextFileType) { \
56 (_pFileType)->h.pNext = (_pNextFileType); \
57 (_pFileType)->h.pPrev = (_pNextFileType)->h.pPrev; \
58 (_pFileType)->h.pPrev->h.pNext = (_pFileType); \
59 (_pNextFileType)->h.pPrev = (_pFileType); \
62 /* Remove the given file type from its linked list */
63 #define UNLINK_FILE_TYPE(_pFileType) { \
64 (_pFileType)->h.pPrev->h.pNext = (_pFileType)->h.pNext; \
65 (_pFileType)->h.pNext->h.pPrev = (_pFileType)->h.pPrev; \
68 /* Return true if given two strings are equal */
69 #define STRING_EQUAL(str, cmpstr) (strcmp ((str), (cmpstr)) == 0)
72 Called by the IL when EFS function is called. Calls the individual
73 Init() function for each file type to be supported by EFS.
75 extern ilBool _ilefsInitStandardFiles (
80 /* ------------------------ ilInitEFS ---------------------------------- */
81 /* Init EFS if not already inited (non-null ptr off of context.)
82 Return ptr to EFS context private or null if error.
84 static ilEFSPrivatePtr ilInitEFS (
88 register ilEFSPrivatePtr pPriv;
90 /* If EFS file type data not present malloc and zero it, and then point
91 context pAlloc to it - if not, could recurse forever.
93 context->error = IL_OK;
94 pPriv = (ilEFSPrivatePtr)((ilContextPtr)context)->pAlloc[IL_CONTEXT_ALLOC_EFS];
96 pPriv = (ilEFSPrivatePtr)IL_MALLOC (sizeof (ilEFSPrivateRec));
98 context->error = IL_ERROR_MALLOC;
99 return (ilEFSPrivatePtr)NULL;
101 ((ilContextPtr)context)->pAlloc[IL_CONTEXT_ALLOC_EFS] = (ilPtr)pPriv;
103 /* Init file type list to null. */
104 pPriv->fileTypeHead.pNext = pPriv->fileTypeHead.pPrev =
105 (ilEFSFileTypePtr)&pPriv->fileTypeHead;
106 pPriv->replacedFileTypeHead.pNext = pPriv->replacedFileTypeHead.pPrev =
107 (ilEFSFileTypePtr)&pPriv->replacedFileTypeHead;
109 /* Call to external lib(s) to callback and add each file type */
110 if (!_ilefsInitStandardFiles (context)) {
112 return (ilEFSPrivatePtr)NULL;
119 /* ================================== FILE TYPE CODE =============================== */
121 /* ------------------------ ilFindFileType ---------------------------------- */
122 /* Find the file type with the given "name" in the list of file types whose
123 head is pointed to by "pListHead". Return ptr to found file type or null.
125 static ilEFSFileTypePtr ilFindFileType (
127 ilEFSFileTypePtr pListHead
130 register ilEFSFileTypePtr pFileType;
132 pFileType = pListHead->h.pNext;
133 while (pFileType != pListHead) {
134 if (STRING_EQUAL (name, pFileType->info.name))
135 return pFileType; /* found, EXIT */
136 pFileType = pFileType->h.pNext;
138 return (ilEFSFileTypePtr)NULL; /* not found, return null */
142 /* ------------------------ ilAddFileTypeToList --------------------------- */
143 /* Add the file type pointed to by "pFileType" to the list of file types whose
144 head is pointed to by "pListHead". Element is placed in list based its
147 static void ilAddFileTypeToList (
148 register ilEFSFileTypePtr pFileType,
149 ilEFSFileTypePtr pListHead
152 register ilEFSFileTypePtr pListFileType;
153 register int checkOrder;
155 checkOrder = pFileType->info.checkOrder;
156 pListFileType = pListHead->h.pNext;
157 while (pListFileType != pListHead) {
158 if (checkOrder > pListFileType->info.checkOrder)
159 break; /* spot found; break */
160 pListFileType = pListFileType->h.pNext;
162 LINK_FILE_TYPE (pFileType, pListFileType) /* insert in front of pListFileType */
166 /* ------------------------ ilEFSAddFileType ---------------------------- */
167 /* Public function: see spec.
170 /* Object Destroy() function for file type objects. */
171 static void ilDestroyFileType (
172 register ilEFSFileTypePtr pFileType
175 ilEFSPrivatePtr pPriv;
176 register ilEFSFileTypePtr pReplaced;
178 pPriv = (ilEFSPrivatePtr)
179 ((ilContextPtr)(pFileType->h.o.p.context))->pAlloc[IL_CONTEXT_ALLOC_EFS];
181 /* Remove file type from its current list. Search the "replaced" list for a
182 file type of same name; if found, move it from replaced to active list.
184 UNLINK_FILE_TYPE (pFileType)
185 pReplaced = ilFindFileType (pFileType->info.name,
186 (ilEFSFileTypePtr)&pPriv->replacedFileTypeHead);
188 UNLINK_FILE_TYPE (pReplaced)
189 ilAddFileTypeToList (pReplaced, (ilEFSFileTypePtr)&pPriv->fileTypeHead);
194 ilEFSFileType ilEFSAddFileType (
196 register ilEFSFileTypeInfo *pInfo,
200 ilEFSPrivatePtr pPriv;
202 register ilEFSFileTypePtr pFileType, pReplace;
203 register unsigned long openModes;
205 /* masks for defined bits in ilEFSFileTypeInfo - others invalid */
206 #define OPEN_MODE_MASKS (1<<IL_EFS_READ | 1<<IL_EFS_READ_SEQUENTIAL | 1<<IL_EFS_WRITE)
207 #define ATTRIBUTES_MASKS (IL_EFS_MULTI_PAGE_READS | IL_EFS_MULTI_PAGE_WRITES | \
208 IL_EFS_MASK_READS | IL_EFS_MASK_WRITES | IL_EFS_SCALEABLE_READS)
211 context->error = IL_ERROR_PAR_NOT_ZERO;
212 return (ilEFSFileType)NULL;
215 /* Validate *pInfo: strings present, unused mask bits zero, functions right. */
216 if ((strlen (pInfo->name) > (IL_EFS_MAX_NAME_CHARS - 1))
217 || (strlen (pInfo->displayName) > (IL_EFS_MAX_DISPLAY_NAME_CHARS - 1))
218 || (pInfo->nExtensions > IL_EFS_MAX_EXTENSIONS))
219 goto badFileTypeInfo;
221 for (i = 0; i < pInfo->nExtensions; i++)
222 if (strlen (pInfo->extensions[i]) > (IL_EFS_MAX_EXTENSION_CHARS - 1))
223 goto badFileTypeInfo;
225 openModes = pInfo->openModes;
226 if ((openModes & ~OPEN_MODE_MASKS)
227 || (pInfo->attributes & ~ATTRIBUTES_MASKS))
228 goto badFileTypeInfo;
230 if (((!pInfo->Open || !pInfo->Open) && openModes)
231 || (!pInfo->Seek && (openModes & 1<<IL_EFS_READ)
232 && (pInfo->attributes & IL_EFS_MULTI_PAGE_READS))
233 || ((!pInfo->GetPageInfo || !pInfo->ReadImage)
234 && (openModes & (1<<IL_EFS_READ | 1<<IL_EFS_READ_SEQUENTIAL)))
235 || (!pInfo->WriteImage && (openModes & 1<<IL_EFS_WRITE)))
236 goto badFileTypeInfo;
238 for (i = 0; i < IL_EFS_TYPE_RESERVED_SIZE; i++)
239 if (pInfo->reserved[i] != 0)
240 goto badFileTypeInfo;
242 /* Init EFS file types if not already inited. */
243 if (!(pPriv = ilInitEFS (context)))
244 return (ilEFSFileType)NULL;
246 /* Create a file type object, exit if failure. Set *pInfo into it. */
247 pFileType = (ilEFSFileTypePtr)_ilCreateObject (context, IL_EFS_FILE_TYPE,
248 ilDestroyFileType, sizeof (ilEFSFileTypeRec));
249 if (!pFileType) return (ilEFSFileType)NULL;
250 pFileType->info = *pInfo;
252 /* Search the active list for file type with same name. If found, remove it
253 from active list and add to replaced list, in front of any with same name.
255 pReplace = ilFindFileType (pFileType->info.name,
256 (ilEFSFileTypePtr)&pPriv->fileTypeHead);
258 ilEFSFileTypePtr pReplaceFront;
259 UNLINK_FILE_TYPE (pReplace)
260 pReplaceFront = ilFindFileType (pFileType->info.name,
261 (ilEFSFileTypePtr)&pPriv->fileTypeHead);
263 pReplaceFront = (ilEFSFileTypePtr)&pPriv->fileTypeHead;
264 LINK_FILE_TYPE (pReplace, pReplaceFront)
267 /* Add the file type to the active list */
268 ilAddFileTypeToList (pFileType, (ilEFSFileTypePtr)&pPriv->fileTypeHead);
270 context->error = IL_OK;
271 return (ilEFSFileType)pFileType;
273 /* goto point if invalid file type info: return error. */
275 context->error = IL_ERROR_EFS_FILE_TYPE_INFO;
276 return (ilEFSFileType)NULL;
280 /* ------------------------ ilEFSGetFileTypeInfo ---------------------------- */
281 /* Public function: see spec.
283 ilBool ilEFSGetFileTypeInfo (
284 ilEFSFileType fileType,
285 ilEFSFileTypeInfo *pInfo
288 register ilEFSFileTypePtr pFileType;
290 pFileType = (ilEFSFileTypePtr)fileType;
291 if (pFileType->h.o.p.objectType != IL_EFS_FILE_TYPE) {
292 pFileType->h.o.p.context->error = IL_ERROR_OBJECT_TYPE;
296 *pInfo = pFileType->info;
297 pFileType->h.o.p.context->error = IL_OK;
302 /* ------------------------ ilEFSListFileTypes ------------------------------ */
303 /* Public function: see spec.
305 ilBool ilEFSListFileTypes (
308 ilEFSFileType **pfileTypes
311 ilEFSPrivatePtr pPriv;
312 register int nFileTypes;
313 register ilEFSFileTypePtr pFileType;
314 register ilEFSFileType *pfileType;
317 *pfileTypes = (ilEFSFileType *)NULL;
319 /* Init EFS file types if not already inited. */
320 if (!(pPriv = ilInitEFS (context)))
323 /* Count the number of file types in the list */
325 pFileType = pPriv->fileTypeHead.pNext;
326 while (pFileType != (ilEFSFileTypePtr)&pPriv->fileTypeHead) {
327 pFileType = pFileType->h.pNext;
331 /* Malloc space for returned file types - use malloc(); caller uses free().
332 If no file types, still malloc something to return non-null ptr.
334 pfileType = (ilEFSFileType *)malloc ((nFileTypes > 0) ?
335 nFileTypes * sizeof (ilEFSFileType) : 4);
337 context->error = IL_ERROR_MALLOC;
341 /* Return # of file types; traverse list to return ptrs to them. */
342 *pfileTypes = pfileType;
343 *pNFileTypes = nFileTypes;
344 pFileType = pPriv->fileTypeHead.pNext;
345 while (nFileTypes-- > 0) {
346 *pfileType++ = (ilEFSFileType)pFileType;
347 pFileType = pFileType->h.pNext;
350 context->error = IL_OK;
355 /* =================================== FILE CODE ================================== */
358 /* --------------------------- ilEFSOpenFile ------------------------------- */
359 /* Public function: see spec.
362 /* Object Destroy() function for file objects. */
363 static void ilDestroyFile (
367 register ilEFSFileTypePtr pFileType;
369 /* Get ptr to file type; if null, file not actually open yet; skip Close() */
370 pFileType = (ilEFSFileTypePtr)pFile->info.fileType;
372 (*pFileType->info.Close) (pFile);
376 ilEFSFile ilEFSOpen (
379 unsigned int openMode,
380 unsigned long searchOptions,
385 ilEFSPrivatePtr pPriv;
386 register ilEFSFilePtr pFile;
387 register ilEFSFileTypePtr pFileType, pListHead;
391 char extension [IL_EFS_MAX_EXTENSION_CHARS];
393 /* Validate pOptions, openMode (set readOpen true if a read). */
394 context->error = IL_OK;
396 context->error = IL_ERROR_PAR_NOT_ZERO;
397 return (ilEFSFileType)NULL;
401 case IL_EFS_READ_SEQUENTIAL:
402 readOpen = TRUE; break;
404 readOpen = FALSE; break;
406 context->error = IL_ERROR_EFS_OPEN_MODE;
407 return (ilEFSFile)NULL;
410 /* Init EFS file types if not already inited. */
411 if (!(pPriv = ilInitEFS (context)))
412 return (ilEFSFile)NULL;
414 /* Add a file type object - goto openError to destroy it if an error later. */
415 pFile = (ilEFSFilePtr)_ilCreateObject (context, IL_EFS_FILE, ilDestroyFile,
416 sizeof (ilEFSFileRec));
417 if (!pFile) return (ilEFSFile)NULL;
419 /* Find pFileType for this file, searches enabled by mask in searchOptions.
420 First try typeName, if non-null. When found at any point: if openMode
421 not supported, error - except for checking mode - else call Open() for
422 the file type. If it returns any error other than "not mine" abort.
424 pFileType = (ilEFSFileTypePtr)NULL;
425 pListHead = (ilEFSFileTypePtr)&pPriv->fileTypeHead;
426 if (typeName && (searchOptions & IL_EFS_BY_TYPE_NAME)) {
427 pFileType = ilFindFileType (typeName, pListHead);
428 if (pFileType) { /* file type found */
429 if (!(pFileType->info.openModes & (1 << openMode))) {
430 context->error = IL_ERROR_EFS_OPEN_MODE;
433 pOpenPriv = (*pFileType->info.Open) (pFileType, fileName, openMode, &nPages);
435 if (context->error == IL_ERROR_EFS_NOT_MINE)
436 pFileType = (ilEFSFileTypePtr)NULL; /* try next search method */
439 pFile->info.howFound = IL_EFS_BY_CHECKING;
441 } /* END open by type name */
444 /* If not found, search for extension if enabled. */
445 if (!pFileType && (searchOptions & IL_EFS_BY_EXTENSION)) {
447 register ilEFSFileTypePtr pSearch;
450 pExtension = strrchr (fileName, '.');
451 if (pExtension) { /* is a "." in fileName */
452 pExtension++; /* point past "." */
453 nChars = strlen (pExtension);
454 if (nChars > (IL_EFS_MAX_EXTENSION_CHARS - 1))
455 nChars = IL_EFS_MAX_EXTENSION_CHARS - 1;
456 bcopy (pExtension, extension, nChars); /* extract "extension" */
457 extension [nChars] = 0;
459 /* Search list for extension match until pFileType found or list done */
460 pSearch = pListHead->h.pNext;
461 while (!pFileType && (pSearch != pListHead)) {
462 register int nExtensions = pSearch->info.nExtensions;
463 while (nExtensions-- > 0)
464 if (STRING_EQUAL (extension, pSearch->info.extensions[nExtensions])) {
465 pFileType = pSearch; /* extension found; quit */
466 pFile->info.howFound = IL_EFS_BY_CHECKING;
469 pSearch = pSearch->h.pNext;
472 if (!(pFileType->info.openModes & (1 << openMode))) {
473 context->error = IL_ERROR_EFS_OPEN_MODE;
476 pOpenPriv = (*pFileType->info.Open) (pFileType, fileName, openMode, &nPages);
478 if (context->error == IL_ERROR_EFS_NOT_MINE)
479 pFileType = (ilEFSFileTypePtr)NULL;
483 } /* END have extension */
484 } /* END open by extension */
487 /* If not found, search by checking if a read openMode. For each file type,
488 try open if enabled (checkOrder != 0) and openMode supported for file type.
490 if (!pFileType && readOpen && (searchOptions & IL_EFS_BY_CHECKING)) {
491 register ilEFSFileTypePtr pSearch;
493 pSearch = pListHead->h.pNext;
494 while (pSearch != pListHead) {
495 if (pSearch->info.checkOrder && (pSearch->info.openModes & (1 << openMode))) {
496 pOpenPriv = (*pSearch->info.Open) (pSearch, fileName, openMode, &nPages);
498 pFileType = pSearch; /* found right file type; break */
499 pFile->info.howFound = IL_EFS_BY_CHECKING;
502 else if (context->error != IL_ERROR_EFS_NOT_MINE)
503 goto openError; /* some error; give up */
505 pSearch = pSearch->h.pNext;
507 } /* END open by checking */
509 /* If not found above, error: can't find file type handler for this file. */
511 context->error = IL_ERROR_EFS_NO_FILE_TYPE;
515 /* File type found. Fill in info for the file, return pFile. The object's
516 pPrivate is set to the ptr returned from file type's Open().
518 pFile->o.p.pPrivate = pOpenPriv;
519 pFile->info.fileType = (ilEFSFileType)pFileType;
520 pFile->info.openMode = openMode;
521 pFile->info.attributes = pFileType->info.attributes;
522 pFile->info.nPages = nPages;
523 pFile->pFileType = pFileType;
525 context->error = IL_OK;
526 return (ilEFSFile)pFile; /* success; return file */
528 /* openError: goto here on error after file object created. The Open() was not
529 successful, so set fileType to null so ilDestroyFile() does not call Close().
533 error = context->error; /* save error code */
534 pFile->info.fileType = (ilEFSFileType)NULL;
535 ilDestroyObject ((ilObject)pFile);
536 context->error = error; /* restore error code */
537 return (ilEFSFile)NULL;
542 /* ------------------------ ilEFSGetFileInfo ---------------------------- */
543 /* Public function: see spec.
545 ilBool ilEFSGetFileInfo (
547 ilEFSFileInfo *pInfo /* RETURNED */
550 register ilEFSFilePtr pFile;
552 pFile = (ilEFSFilePtr)file;
553 if (pFile->o.p.objectType != IL_EFS_FILE) {
554 pFile->o.p.context->error = IL_ERROR_OBJECT_TYPE;
558 /* Return file info; fill in "inUse": file in use if refCount > 1 */
559 *pInfo = pFile->info;
560 pInfo->inUse = (pFile->o.refCount > 1);
561 pFile->o.p.context->error = IL_OK;
566 /* ------------------------ ilEFSSeek ---------------------------- */
567 /* Public function: see spec.
575 register ilEFSFilePtr pFile;
577 pFile = (ilEFSFilePtr)file;
579 pFile->o.p.context->error = IL_ERROR_PAR_NOT_ZERO;
582 if (pFile->o.p.objectType != IL_EFS_FILE) {
583 pFile->o.p.context->error = IL_ERROR_OBJECT_TYPE;
587 /* Validate that file was opened for random read; error if not. */
588 if (pFile->info.openMode != IL_EFS_READ) {
589 pFile->o.p.context->error = IL_ERROR_EFS_OPEN_MODE;
593 /* Call Seek() only if multi-page reads supported; not error if not. */
594 pFile->o.p.context->error = IL_OK;
595 if (!(pFile->info.attributes & IL_EFS_MULTI_PAGE_READS))
597 else return (*pFile->pFileType->info.Seek) (file, page);
601 /* ------------------------ ilEFSGetPageInfo ---------------------------- */
602 /* Public function: see spec.
604 ilBool ilEFSGetPageInfo (
609 register ilEFSFilePtr pFile;
611 pFile = (ilEFSFilePtr)file;
612 if (pFile->o.p.objectType != IL_EFS_FILE) {
613 pFile->o.p.context->error = IL_ERROR_OBJECT_TYPE;
617 /* Validate that file was opened for read; call GetPageInfo() if so. */
618 if ((pFile->info.openMode != IL_EFS_READ)
619 && (pFile->info.openMode != IL_EFS_READ_SEQUENTIAL)) {
620 pFile->o.p.context->error = IL_ERROR_EFS_OPEN_MODE;
624 pFile->o.p.context->error = IL_OK;
625 return (*pFile->pFileType->info.GetPageInfo) (file, pInfo);
629 /* ------------------------ ilEFSReadImage ---------------------------- */
630 /* Public function: see spec.
632 ilBool ilEFSReadImage (
635 unsigned int readMode,
641 register ilEFSFilePtr pFile;
643 pFile = (ilEFSFilePtr)file;
645 pFile->o.p.context->error = IL_ERROR_PAR_NOT_ZERO;
648 if ((pipe->objectType != IL_PIPE) || (pFile->o.p.objectType != IL_EFS_FILE)) {
649 pFile->o.p.context->error = IL_ERROR_OBJECT_TYPE;
653 /* Validate readMode: mask allowed only if supported by file type. */
655 case IL_EFS_READ_MAIN:
657 case IL_EFS_READ_MASK:
658 if (pFile->pFileType->info.attributes & IL_EFS_MASK_READS)
659 break; /* else fall thru for error */
661 pFile->o.p.context->error = IL_ERROR_EFS_READ_MODE;
665 /* Validate that file was opened for read. */
666 if ((pFile->info.openMode != IL_EFS_READ)
667 && (pFile->info.openMode != IL_EFS_READ_SEQUENTIAL)) {
668 pFile->o.p.context->error = IL_ERROR_EFS_OPEN_MODE;
672 /* If pipe element added successfully inc file's refCount to mark in use,
673 and add file to list of objects to be destroyed when pipe emptied.
675 pFile->o.p.context->error = IL_OK;
676 if ((*pFile->pFileType->info.ReadImage) (pipe, file, readMode, width, height)) {
678 return _ilAddPipeDestroyObject (pipe, (ilObject)pFile);
684 /* ------------------------ ilEFSWriteImage ---------------------------- */
685 /* Public function: see spec.
687 ilBool ilEFSWriteImage (
692 ilClientImage maskImage,
696 register ilEFSFilePtr pFile;
698 pFile = (ilEFSFilePtr)file;
700 pFile->o.p.context->error = IL_ERROR_PAR_NOT_ZERO;
703 if ((pipe->objectType != IL_PIPE) || (pFile->o.p.objectType != IL_EFS_FILE)) {
704 pFile->o.p.context->error = IL_ERROR_OBJECT_TYPE;
708 /* Validate that file was opened for write. */
709 if (pFile->info.openMode != IL_EFS_WRITE) {
710 pFile->o.p.context->error = IL_ERROR_EFS_OPEN_MODE;
714 /* If file type doesnt handle masks, ignore maskImage, else validate it */
716 if (!(pFile->pFileType->info.attributes & IL_EFS_MASK_WRITES))
717 maskImage = (ilClientImage)NULL;
720 register const ilImageDes *pDes;
721 register const ilImageFormat *pFormat;
723 if (!ilQueryClientImage (maskImage, &pInfo, 0))
726 pFormat = pInfo->pFormat;
727 if ((pDes->compression != IL_UNCOMPRESSED)
728 || (pDes->nSamplesPerPixel != 1)
729 || (pFormat->rowBitAlign != 32)
730 || (pFormat->nBitsPerSample[0] != 1)) {
731 pFile->o.p.context->error = IL_ERROR_EFS_OPEN_MODE;
737 /* If pipe element added successfully inc file's refCount to mark in use,
738 and add file/maskImage to list of objects to be destroyed when pipe emptied.
740 pFile->o.p.context->error = IL_OK;
741 if ((*pFile->pFileType->info.WriteImage) (pipe, file, xRes, yRes, maskImage)) {
743 ((ilObjectPtr)maskImage)->refCount++;
744 _ilAddPipeDestroyObject (pipe, maskImage);
747 return _ilAddPipeDestroyObject (pipe, (ilObject)pFile);