home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD2.mdf / c / library / dos / grafik / disptiff / cutil.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-12-15  |  8.2 KB  |  444 lines

  1. /*
  2.  * C utilities for the Tag Image File Format routines
  3.  */
  4.  
  5. #include "tiff.h"
  6. #define NOWINDOWS
  7. #define NODEBUG 1        /* VJ 11/10 */
  8. #define SHORT_TYPE 3        /* BGM 11/12/87 */
  9.  
  10. #ifndef NULL
  11. #define NULL 0L
  12. #endif /* NULL */
  13.  
  14. typedef char *va_list;
  15.  
  16. #define va_start(ap,v) ap = (va_list)&v + sizeof(v)
  17. #define va_arg(ap,t) ((t*)(ap += sizeof(t)))[-1]
  18. #define va_end(ap) ap = NULL
  19.  
  20. static char temp[160];
  21. extern int vsprintf();
  22.  
  23. #ifdef NOWINDOWS    /* Windows-specific stuff */
  24.  
  25. extern void write();
  26.  
  27. #else
  28.  
  29. #define GMEM_LOCKCOUNT 0x00ff
  30. extern SHORT pascal GlobalFlags();
  31. extern char far * far pascal GlobalLock();
  32. extern BOOL far pascal GlobalUnlock();
  33. extern SHORT far pascal GlobalAlloc();
  34. extern void far pascal GlobalFree();
  35. extern void far pascal TextOut();
  36. extern unsigned short far pascal GetDC();
  37. extern void far pascal ReleaseDC();
  38. extern unsigned short MainWindow;
  39.  
  40. #define GHND    0x0040        /* fixed + zeroinit */
  41.  
  42. #endif /* NOWINDOWS */
  43.  
  44. extern unsigned short tlRead();
  45. extern LONG bigRead();
  46. extern SHORT tdosAlloc();
  47. extern void tdosFree();
  48.  
  49. extern BOOL _TIFF_reorder_bytes;
  50. extern BOOL _TIFF_debug_flag;
  51.  
  52. /* allocate up to one megabyte of data */
  53. LONGPTR
  54. bigalloc(size)
  55. LONG size;
  56. {
  57. #ifdef NOWINDOWS    /* non-Windows allocator */
  58.  
  59.     /* convert to paragraphs */
  60.     LONG temp = (size + 15) >> 4;    /* convert to paragraphs */
  61.     SHORT segment;
  62.  
  63.     /* must be < 1 megabyte */
  64.     if(HIWORD(temp))
  65.     {
  66.         return((LONGPTR)0L);
  67.     }
  68.  
  69.     if(!(segment = tdosAlloc(LOWORD(temp))))
  70.     {
  71.         return((LONGPTR)0L);
  72.     }
  73.     temp = (LONG)segment;
  74.     temp <<= 16;
  75.     return((LONGPTR)temp);
  76.  
  77. #else        /* Windows allocator */
  78.  
  79.     LONGPTR temp;
  80.     SHORT handle;
  81.  
  82.     /* get the space and make room for the handle */
  83.     handle = GlobalAlloc((SHORT)GHND, (LONG)(size + (LONG)SHORT_SIZE));
  84.     if(!handle)
  85.     {
  86.         return((LONGPTR)0L);
  87.     }
  88.  
  89.     /* lock the memory */
  90.     temp = GlobalLock(handle);
  91.     if(!temp)
  92.     {
  93.         GlobalFree(handle);
  94.         return((LONGPTR)0L);
  95.     }
  96.  
  97.     /* store the handle, adjust the pointer, and then return */
  98.     *((SHORT far *)temp) = handle;
  99.     return((LONGPTR)(temp + SHORT_SIZE));
  100.  
  101. #endif /* NOWINDOWS */
  102. }
  103.  
  104. /* free data allocated by bigalloc() */
  105. void
  106. bigfree(memptr)
  107. LONGPTR memptr;
  108. {
  109. #ifdef NOWINDOWS    /* non-Windows */
  110.  
  111.     LONG temp = (LONG)memptr;
  112.  
  113.     if(!memptr)
  114.     {
  115.         return;
  116.     }
  117.  
  118.     /* must be of form SEG:0 if it was returned from bigalloc() */
  119.     if(LOWORD(temp))
  120.     {
  121.         return;
  122.     }
  123.     tdosFree(HIWORD(temp));
  124.  
  125. #else        /* Windows */
  126.  
  127.     SHORT handle;
  128.  
  129.     /* mustn't be a null pointer */
  130.     if(!memptr)
  131.     {
  132.         return;
  133.     }
  134.  
  135.     /* get the handle */
  136.     memptr -= SHORT_SIZE;
  137.     handle = *((SHORT far *)memptr);
  138.  
  139.     /* free the memory */
  140.     /* this is kind of kludgie, but ... */
  141.     while( GlobalFlags(handle) & GMEM_LOCKCOUNT > 0 ) {
  142.         GlobalUnlock(handle);
  143.     }
  144.     GlobalFree(handle);
  145.     return;
  146.  
  147. #endif /* NOWINDOWS */
  148. }
  149.  
  150. /* reorder bytes if necessary */
  151. void
  152. reorder(data, size)
  153. LONGPTR data;
  154. SHORT size;
  155. {
  156.     if(_TIFF_reorder_bytes)
  157.     {
  158.         LONGPTR end = (data + size) - 1;
  159.         char temp;
  160.         while(data < end)
  161.         {
  162.             temp = *data;
  163.             *data++ = *end;
  164.             *end-- = temp;
  165.         }
  166.     }
  167. }
  168.  
  169. /* check if supplied value is correct version number */
  170. BOOL
  171. correct_version(value)
  172. SHORT value;
  173. {
  174.     /*
  175.      * For now, just compare to legal version number.  But this
  176.      * might get more complex as time goes on.
  177.      */
  178.     if(value == LEGAL_VERSION)
  179.     {
  180.         return(TRUE);
  181.     }
  182.     else
  183.     {
  184.         return(FALSE);
  185.     }
  186. }
  187.  
  188. /* return the length of a given type */
  189. SHORT
  190. type_length(type)
  191. SHORT type;
  192. {
  193.     static SHORT length_array[] =
  194.     {
  195.         BYTE_SIZE,
  196.         ASCII_SIZE,
  197.         SHORT_SIZE,
  198.         LONG_SIZE,
  199.         RATIONAL_SIZE,
  200.     };
  201.  
  202.     if(type < 1 || type > ELEMENTS(length_array))
  203.     {
  204.         return(0);
  205.     }
  206.     else
  207.     {
  208.         return(length_array[--type]);
  209.     }
  210. }
  211.  
  212. /* get value of tag */
  213. SHORT
  214. value_of(dirent, value)
  215. TIFF_DIR_ENTRY far *dirent;
  216. LONGPTR value;
  217. {
  218.     SHORT tlen = type_length(dirent->type);
  219.     SHORT code = DIRECT_VALUE;
  220.     LONG len;
  221.     long x;
  222.     LONGPTR cp;
  223.  
  224.     if(tlen < 1)
  225.     {
  226.         return(ERROR_VALUE);
  227.     }
  228.  
  229.     /* calculate real length */
  230.     len = (LONG)tlen;
  231.     len *= dirent->length;
  232.  
  233.     /* if longer than a LONG, only return the pointer to the data */
  234.     if(len >= LONG_SIZE)
  235.     {
  236.         len = LONG_SIZE;
  237.         code = INDIRECT_VALUE;
  238.     }
  239.  
  240.     /* move the value */
  241.     cp = (LONGPTR)&(dirent->value_offset);
  242.     x = (long)len;
  243.     while(x-- > 0)
  244.     {
  245.         *value++ = *cp++;
  246.     }
  247.  
  248.     return(code);
  249. }
  250.  
  251. /* read pertinent data from currently-pointed-to directory entry */
  252. BOOL
  253. read_dir(fhandle, dirent)
  254. SHORT fhandle;
  255. TIFF_DIR_ENTRY far *dirent;
  256. {
  257.     LONG littleRead();
  258.  
  259.     if(littleRead(fhandle, dirent, (LONG)TIFF_DIR_ENTRY_SIZE) <
  260.       TIFF_DIR_ENTRY_SIZE)
  261.     {
  262.         return(TRUE);
  263.     }
  264.  
  265.     /* reorder bytes if necessary */
  266.     reorder((SHORT far *)&(dirent->tag), SHORT_SIZE);
  267.     reorder((SHORT far *)&(dirent->type), SHORT_SIZE);
  268.     reorder((LONG far *)&(dirent->length), LONG_SIZE);
  269.     if(dirent->type == SHORT_TYPE  && dirent->length == 1) {
  270.         reorder((SHORT far *)&(dirent->value_offset), SHORT_SIZE);
  271.     } else {
  272.         reorder((LONG far *)&(dirent->value_offset), LONG_SIZE);
  273.     }
  274.  
  275.     return(FALSE);
  276. }
  277.  
  278. /* return entry count and subfile type of referenced IFD */
  279. BOOL
  280. access_ifd(fhandle, offset, dirent, entry_count, subfile_type,
  281.   next_dir_offset)
  282. SHORT fhandle;
  283. LONG offset;
  284. TIFF_DIR_ENTRY far *dirent;
  285. SHORT *entry_count;
  286. SHORT *subfile_type;
  287. LONG *next_dir_offset;
  288. {
  289.     BOOL retcode = FALSE;
  290.     LONG next_offset;
  291.     LONG lseek();
  292.  
  293.     /* seek to appropriate file position and exit if seek fails */
  294.     if(lseek(fhandle, offset, 0) != offset)
  295.     {
  296.         return(TRUE);
  297.     }
  298.  
  299.     /* attempt to read entry count */
  300.     if(littleRead(fhandle, (SHORT far *)entry_count, (LONG)SHORT_SIZE) <
  301.       SHORT_SIZE)
  302.     {
  303.         return(TRUE);
  304.     }
  305.     offset += SHORT_SIZE;
  306.  
  307.     /* reorder bytes if necessary */
  308.     reorder((SHORT far *)entry_count, SHORT_SIZE);
  309.  
  310.     /* entry count must be >= 1 (for now and maybe forever) */
  311.     if(*entry_count < 1)
  312.     {
  313.         return(TRUE);
  314.     }
  315.  
  316.     /* read directory entry at current file offset and return info */
  317.     if(read_dir(fhandle, dirent))
  318.     {
  319.         return(TRUE);
  320.     }
  321.     offset += TIFF_DIR_ENTRY_SIZE;
  322.  
  323.     /* first entry must be "SubfileType" or else it's an error */
  324.     if(dirent->tag != SUBFILE_TYPE_TAG)
  325.     {
  326.         return(TRUE);
  327.     }
  328.  
  329.     /* retrieve value (subfile type in this case) */
  330.     if(value_of(dirent, (LONGPTR)subfile_type) != DIRECT_VALUE)
  331.     {
  332.         return(TRUE);
  333.     }
  334.  
  335.     /* seek (relative) to end of IFD and read offset of next IFD */
  336.     next_offset = (LONG)*entry_count - 1;
  337.     next_offset *= TIFF_DIR_ENTRY_SIZE;
  338.     if(lseek(fhandle, next_offset, 1) == (LONG)(-1))
  339.     {
  340.         retcode = TRUE;
  341.     }
  342.     else if(littleRead(fhandle, (LONG far *)next_dir_offset, (LONG)LONG_SIZE)
  343.       != LONG_SIZE)
  344.     {
  345.         retcode = TRUE;
  346.     }
  347.  
  348.     /* seek back to where we were before seek to end of IFD */
  349.     if(lseek(fhandle, offset, 0) != offset)
  350.     {
  351.         retcode = TRUE;
  352.     }
  353.     return(retcode);
  354. }
  355.  
  356. LONG
  357. bigRead(fhandle, buffer, size)
  358. SHORT fhandle;
  359. LONGPTR buffer;
  360. LONG size;
  361. {
  362.     SHORT pages = HIWORD(size);
  363.     unsigned short rest = (unsigned short)LOWORD(size);
  364.     unsigned short bytes;
  365.     unsigned long total = 0;
  366.  
  367.     while(pages-- > 0)
  368.     {
  369.         int repeat = 2;
  370.         while(repeat-- > 0)
  371.         {
  372.             bytes = tlRead(fhandle, buffer, 0x8000);
  373.             total += (unsigned long)bytes;
  374.             if(bytes != 0x8000)
  375.             {
  376.                 return((LONG)total);
  377.             }
  378.             buffer += bytes;
  379.         }
  380.     }
  381.     bytes = tlRead(fhandle, buffer, rest);
  382.     total += (unsigned long)bytes;
  383.     return((LONG)total);
  384. }
  385.  
  386. LONG littleRead(fhandle,buffer,size)
  387. SHORT fhandle;
  388. LONGPTR buffer;
  389. LONG size;
  390. {
  391.     long bytes;
  392.  
  393.     bytes = tlRead(fhandle,buffer,size);
  394.     
  395.     return(bytes);
  396. }
  397.  
  398. void
  399. copybytes(to, from, amount)
  400. LONGPTR to;
  401. LONGPTR from;
  402. LONG amount;
  403. {
  404.     if(!to || !from)
  405.     {
  406.         return;
  407.     }
  408.     while(amount-- > 0)
  409.     {
  410.         *to++ = *from++;
  411.     }
  412. }
  413.  
  414. void
  415. debug(fmt)
  416. char *fmt;
  417.  
  418. {
  419. #ifndef  NODEBUG            /* vj, 11/10 */
  420.     va_list arg_ptr;
  421.     if(_TIFF_debug_flag)
  422.     {
  423. #ifndef NOWINDOWS
  424.         unsigned short hdc;
  425. #endif /* not NOWINDOWS */
  426.         int len;
  427.         va_start(arg_ptr, fmt);
  428.         len = vsprintf(temp, fmt, arg_ptr);
  429. #ifdef NOWINDOWS
  430.         write(1, temp, len);
  431. #else
  432.         if(temp[len - 1] == '\n')
  433.         {
  434.             temp[--len] = '\0';
  435.         }
  436.         hdc = GetDC(MainWindow);
  437.         TextOut(hdc, 40, 40, (LONGPTR)temp, len);
  438.         ReleaseDC(MainWindow, hdc);
  439. #endif /* NOWINDOWS */
  440.         va_end(arg_ptr);
  441.     }
  442. #endif     /* no debug */
  443. }
  444.