home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / rexx / library2 / gbmrexx / gbm / gbmkps.c < prev    next >
C/C++ Source or Header  |  1992-11-04  |  8KB  |  360 lines

  1. /*
  2.  
  3. GBMKPS.C  IBM KIPS support
  4.  
  5. Reads array as 8 bit palettised colour.
  6. Writes 8 bit palettised colour.
  7. Input options: pal,kpl (default: pal)
  8. Output options: pal,kpl (default: pal)
  9.  
  10. */
  11.  
  12. /*...sincludes:0:*/
  13. #include <stdio.h>
  14. #include <ctype.h>
  15. #include <stddef.h>
  16. #include <stdlib.h>
  17. #include <string.h>
  18. #include <memory.h>
  19. #include <malloc.h>
  20. #ifdef AIX
  21. #include <unistd.h>
  22. #else
  23. #include <io.h>
  24. #endif
  25. #include <fcntl.h>
  26. #include <sys/types.h>
  27. #include <sys/stat.h>
  28. #include "standard.h"
  29. #include "gbm.h"
  30.  
  31. /*...vgbm\46\h:0:*/
  32.  
  33. /* Handle case for UNIX machines where O_BINARY has no meaning */
  34.  
  35. #ifndef O_BINARY
  36. #define    O_BINARY    0
  37. #endif
  38. /*...e*/
  39.  
  40. /*...suseful:0:*/
  41. #define    low_byte(w)    ((byte)  ((w)&0x00ff)    )
  42. #define    high_byte(w)    ((byte) (((w)&0xff00)>>8))
  43. #define    make_word(a,b)    (((word)a) + (((word)b) << 8))
  44. /*...e*/
  45. /*...sextension:0:*/
  46. static char *extension(char *fn)
  47.     {
  48.     char    *dot, *slash;
  49.  
  50.     if ( (dot = strrchr(fn, '.')) == NULL )
  51.         return ( NULL );
  52.  
  53.     if ( (slash = strpbrk(fn, "/\\")) == NULL )
  54.         return ( dot + 1 );
  55.  
  56.     return ( ( slash < dot ) ? dot + 1 : NULL );
  57.     }
  58. /*...e*/
  59. /*...ssame:0:*/
  60. static BOOLEAN same(char *s1, char *s2, int n)
  61.     {
  62.     for ( ; n--; s1++, s2++ )
  63.         if ( tolower(*s1) != tolower(*s2) )
  64.             return ( FALSE );
  65.     return ( TRUE );
  66.     }
  67. /*...e*/
  68. /*...sfind_word:0:*/
  69. static char *find_word(char *str, char *substr)
  70.     {
  71.     char    buf [100+1], *s;
  72.     int    len = strlen(substr);
  73.  
  74.     for ( s  = strtok(strcpy(buf, str), " \t,");
  75.           s != NULL;
  76.           s  = strtok(NULL, " \t,") )
  77.         if ( same(s, substr, len) && s [len] == '\0' )
  78.             return ( str + (s - buf) );
  79.     return ( NULL );
  80.     }
  81. /*...e*/
  82.  
  83. static GBMFT kps_gbmft =
  84.     {
  85.     "KIPS",
  86.     "IBM KIPS",
  87.     "KPS",
  88.     GBM_FT_R8|
  89.     GBM_FT_W8,
  90.     };
  91.  
  92. #define    GBM_ERR_KPS_OPEN    ((GBM_ERR) 500)
  93. #define    GBM_ERR_KPS_CREATE    ((GBM_ERR) 501)
  94.  
  95. /*...skps file header definition:0:*/
  96. /*
  97. This defines the 32 byte header found on .KPS and .KPL files.
  98. */
  99.  
  100. #define    KPS_SIGNITURE    "DFIMAG00"
  101.  
  102. typedef struct
  103.     {
  104.     byte    signiture [8];        /* Usually "DFIMAG00"                */
  105.     byte    height_low;    
  106.     byte    height_high;        /* Image height in pixels            */
  107.     byte    width_low;    
  108.     byte    width_high;        /* Image width in pixels             */
  109.     byte    unknown [20];        /* 20 unknown bytes                  */
  110.     } KPS_HEADER;
  111. /*...e*/
  112.  
  113. typedef struct
  114.     {
  115.     char    fn [600+1];
  116.     BOOLEAN    kpl;
  117.     } KPS_PRIV;
  118.  
  119. /*...skps_qft:0:*/
  120. GBM_ERR kps_qft(GBMFT *gbmft)
  121.     {
  122.     *gbmft = kps_gbmft;
  123.     return ( GBM_ERR_OK );
  124.     }
  125. /*...e*/
  126. /*...skps_rhdr:0:*/
  127. GBM_ERR kps_rhdr(char *fn, int fd, GBM *gbm, char *opt)
  128.     {
  129.     BOOLEAN    pal = ( find_word(opt, "pal") != NULL );
  130.     BOOLEAN    kpl = ( find_word(opt, "kpl") != NULL );
  131.     KPS_HEADER kps_header;
  132.     KPS_PRIV *priv = (KPS_PRIV *) gbm -> priv;
  133.     int    w, h;
  134.  
  135.     if ( kpl && pal )
  136.         return ( GBM_ERR_BAD_OPTION );
  137.  
  138.     read(fd, (char *) &kps_header, sizeof(KPS_HEADER));
  139.  
  140.     if ( memcmp(kps_header.signiture, KPS_SIGNITURE, strlen(KPS_SIGNITURE)) )
  141.         return ( GBM_ERR_BAD_MAGIC );
  142.  
  143.     w = make_word(kps_header.width_low , kps_header.width_high );
  144.     h = make_word(kps_header.height_low, kps_header.height_high);
  145.  
  146.     if ( w <= 0 || h <= 0 )
  147.         return ( GBM_ERR_BAD_SIZE );
  148.  
  149.     gbm -> w   = w;
  150.     gbm -> h   = h;
  151.     gbm -> bpp = 8;
  152.  
  153.     /* Keep these for a later kps_rpal() call */
  154.  
  155.     strcpy(priv -> fn, fn);
  156.     priv -> kpl = kpl;
  157.  
  158.     return ( GBM_ERR_OK );
  159.     }
  160. /*...e*/
  161. /*...skps_rpal:0:*/
  162. GBM_ERR kps_rpal(int fd, GBM *gbm, GBMRGB *gbmrgb)
  163.     {
  164.     KPS_PRIV *priv = (KPS_PRIV *) gbm -> priv;
  165.     char    fn2 [600+1], *ext;
  166.  
  167.     fd=fd; /* Suppress 'unref arg' compiler warning */
  168.  
  169.     strcpy(fn2, priv -> fn);
  170.     ext = extension(fn2);
  171.     if ( priv -> kpl )
  172. /*...sread a \46\kpl palette file:16:*/
  173. {
  174. int    fd2, i, w, h;
  175. byte    p [3][0x100];
  176. KPS_HEADER kps_header;
  177.  
  178. if ( ext != NULL )
  179.     strcpy(ext, "kpl");
  180. else
  181.     strcat(fn2, ".kpl");
  182.  
  183. if ( (fd2 = open(fn2, O_RDONLY | O_BINARY)) == -1 )
  184.     return ( GBM_ERR_KPS_OPEN );
  185.  
  186. read(fd2, (char *) &kps_header, sizeof(KPS_HEADER));
  187. if ( memcmp(kps_header.signiture, KPS_SIGNITURE, strlen(KPS_SIGNITURE)) )
  188.     return ( GBM_ERR_BAD_MAGIC );
  189.  
  190. w = make_word(kps_header.width_low , kps_header.width_high );
  191. h = make_word(kps_header.height_low, kps_header.height_high);
  192.  
  193. if ( w != 0x100 || h != 3 )
  194.     return ( GBM_ERR_BAD_SIZE );
  195.  
  196. read(fd2, &(p [0][0]), 0x300);
  197. close(fd2);
  198.  
  199. for ( i = 0; i < 0x100; i++ )
  200.     {
  201.     gbmrgb [i].r = p [0][i];
  202.     gbmrgb [i].b = p [1][i];
  203.     gbmrgb [i].g = p [2][i];
  204.     }
  205. }
  206. /*...e*/
  207.     else
  208. /*...sread a \46\pal palette file:16:*/
  209. {
  210. int    fd2, i;
  211. byte    b [4];
  212.  
  213. if ( ext != NULL )
  214.     strcpy(ext, "pal");
  215. else
  216.     strcat(fn2, ".pal");
  217.  
  218. if ( (fd2 = open(fn2, O_RDONLY | O_BINARY)) == -1 )
  219.     return ( GBM_ERR_KPS_OPEN );
  220.  
  221. for ( i = 0; i < 0x100; i++ )
  222.     {
  223.     read(fd2, (char *) b, 4);
  224.     gbmrgb [i].r = b [0];
  225.     gbmrgb [i].b = b [1];
  226.     gbmrgb [i].g = b [2];
  227.     }
  228. close(fd2);
  229. }
  230. /*...e*/
  231.  
  232.     return ( GBM_ERR_OK );
  233.     }
  234. /*...e*/
  235. /*...skps_rdata:0:*/
  236. GBM_ERR kps_rdata(int fd, GBM *gbm, byte *data)
  237.     {
  238.     int    i, stride;
  239.     byte    *p;
  240.  
  241.     stride = ((gbm -> w + 3) & ~3);
  242.     p = data + ((gbm -> h - 1) * stride);
  243.     for ( i = gbm -> h - 1; i >= 0; i-- )
  244.         {
  245.         read(fd, p, gbm -> w);
  246.         p -= stride;
  247.         }
  248.  
  249.     return ( GBM_ERR_OK );
  250.     }
  251. /*...e*/
  252. /*...skps_w:0:*/
  253. GBM_ERR kps_w(char *fn, int fd, GBM *gbm, GBMRGB *gbmrgb, byte *data, char *opt)
  254.     {
  255.     KPS_HEADER kps_header;
  256.     int    i, stride;
  257.     byte    *p;
  258.     char    fn2 [600+1], *ext;
  259.     BOOLEAN    pal = ( find_word(opt, "pal") != NULL );
  260.     BOOLEAN    kpl = ( find_word(opt, "kpl") != NULL );
  261.  
  262.     if ( gbm -> bpp != 8 )
  263.         return ( GBM_ERR_NOT_SUPP );
  264.  
  265.     if ( pal && kpl )
  266.         return ( GBM_ERR_BAD_OPTION );
  267.  
  268.     memcpy(kps_header.signiture, KPS_SIGNITURE, strlen(KPS_SIGNITURE));
  269.     kps_header.width_low   = low_byte(gbm -> w);
  270.     kps_header.width_high  = high_byte(gbm -> w);
  271.     kps_header.height_low  = low_byte(gbm -> h);
  272.     kps_header.height_high = high_byte(gbm -> h);
  273.     kps_header.unknown [0] = 1;
  274.     memset(&kps_header.unknown [1], 0, 19);
  275.     write(fd, (char *) &kps_header, sizeof(KPS_HEADER));
  276.  
  277.     stride = ((gbm -> w + 3) & ~3);
  278.     p = data + ((gbm -> h - 1) * stride);
  279.     for ( i = gbm -> h - 1; i >= 0; i-- )
  280.         {
  281.         write(fd, p, gbm -> w);
  282.         p -= stride;
  283.         }
  284.  
  285.     strcpy(fn2, fn);
  286.     ext = extension(fn2);
  287.     if ( kpl )
  288. /*...swrite a \46\kpl palette file:16:*/
  289. {
  290. int    fd2, j;
  291. byte    palette [3][0x100];
  292.  
  293. if ( ext != NULL )
  294.     strcpy(ext, "kpl");
  295. else
  296.     strcat(fn2, ".kpl");
  297.  
  298. if ( (fd2 = open(fn2, O_CREAT | O_TRUNC | O_WRONLY | O_BINARY, S_IREAD | S_IWRITE)) == -1 )
  299.     return ( GBM_ERR_KPS_CREATE );
  300.  
  301. kps_header.width_low   = low_byte(0x100);
  302. kps_header.width_high  = high_byte(0x100);
  303. kps_header.height_low  = low_byte(3);
  304. kps_header.height_high = high_byte(3);
  305. write(fd2, (char *) &kps_header, sizeof(KPS_HEADER));
  306.  
  307. for ( j = 0; j < 0x100; j++ )
  308.     {
  309.     palette [0][j] = gbmrgb [j].r;
  310.     palette [1][j] = gbmrgb [j].b;
  311.     palette [2][j] = gbmrgb [j].g;
  312.     }
  313.  
  314. write(fd2, &(palette [0][0]), 0x300);
  315. close(fd2);
  316. }
  317. /*...e*/
  318.     else
  319. /*...swrite a \46\pal palette file:16:*/
  320. {
  321. int    fd2;
  322. byte    b [4];
  323.  
  324. if ( ext != NULL )
  325.     strcpy(ext, "pal");
  326. else
  327.     strcat(fn2, ".pal");
  328.  
  329. if ( (fd2 = open(fn2, O_CREAT | O_TRUNC | O_WRONLY | O_BINARY, S_IREAD | S_IWRITE)) == -1 )
  330.     return ( GBM_ERR_KPS_CREATE );
  331.  
  332. b [3] = 0;
  333. for ( i = 0; i < 0x100; i++ )
  334.     {
  335.     b [0] = gbmrgb [i].r;
  336.     b [1] = gbmrgb [i].b;
  337.     b [2] = gbmrgb [i].g;
  338.     write(fd2, (char *) b, 4);
  339.     }
  340. close(fd2);
  341. }
  342. /*...e*/
  343.  
  344.     return ( GBM_ERR_OK );
  345.     }
  346. /*...e*/
  347. /*...skps_err:0:*/
  348. char *kps_err(GBM_ERR rc)
  349.     {
  350.     switch ( (int) rc )
  351.         {
  352.         case GBM_ERR_KPS_OPEN:
  353.             return ( "can't open complementary palette file" );
  354.         case GBM_ERR_KPS_CREATE:
  355.             return ( "can't create complementary palette file" );
  356.         }
  357.     return ( NULL );
  358.     }
  359. /*...e*/
  360.