home *** CD-ROM | disk | FTP | other *** search
/ Der Mediaplex Sampler - Die 6 von Plex / 6_v_plex.zip / 6_v_plex / DISK5 / WIN_12 / IDEPIX2.ZIP / TIFFACS.ZIP / CUTIL.C < prev    next >
C/C++ Source or Header  |  1993-06-23  |  9KB  |  432 lines

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