home *** CD-ROM | disk | FTP | other *** search
/ Stars of Shareware: Programmierung / SOURCE.mdf / programm / msdos / c / xv221src / xvpm.c < prev    next >
Text File  |  1992-09-24  |  8KB  |  280 lines

  1. /*
  2.  * xvpm.c - load routine for 'pm' format pictures
  3.  *
  4.  * LoadPM(fname, numcols)  -  loads a PM pic, does 24to8 code if nec.
  5.  * WritePM(fp, pic, w, h, r,g,b, numcols, style)
  6.  * WriteRaw(fp, pic, w, h, r,g,b, numcols, style)
  7.  */
  8.  
  9. /*
  10.  * Copyright 1989, 1990, 1991, 1992 by John Bradley and
  11.  *                       The University of Pennsylvania
  12.  *
  13.  * Permission to use, copy, and distribute for non-commercial purposes,
  14.  * is hereby granted without fee, providing that the above copyright
  15.  * notice appear in all copies and that both the copyright notice and this
  16.  * permission notice appear in supporting documentation.
  17.  *
  18.  * The software may be modified for your own purposes, but modified versions
  19.  * may not be distributed.
  20.  *
  21.  * This software is provided "as is" without any expressed or implied warranty.
  22.  *
  23.  * The author may be contacted via:
  24.  *    US Mail:   John Bradley
  25.  *               GRASP Lab, Room 301C
  26.  *               3401 Walnut St.
  27.  *               Philadelphia, PA  19104
  28.  *
  29.  *    Phone:     (215) 898-8813
  30.  *    EMail:     bradley@cis.upenn.edu
  31.  */
  32.  
  33.  
  34. #include "xv.h"
  35. #include "pm.h"
  36.  
  37. pmpic  thePic;
  38.  
  39. static int PMError();
  40. static void flipl();
  41.  
  42.  
  43. /*******************************************/
  44. int LoadPM(fname,nc)
  45.      char *fname;
  46.      int   nc;
  47. /*******************************************/
  48. {
  49.   FILE  *fp;
  50.   int    isize,i,flipit,w,h,rv;
  51.  
  52.   rv = 0;
  53.   thePic.pm_image = NULL;
  54.  
  55.   /* read in the PM picture */
  56.   fp=fopen(fname,READ_BINARY);
  57.   if (!fp) return( PMError("unable to open file") );
  58.   
  59.   flipit = 0;
  60.   fread(&thePic,PM_IOHDR_SIZE,1,fp);
  61.   if (thePic.pm_id != PM_MAGICNO) {
  62.     flipl( (byte *) &thePic.pm_id);
  63.     if (thePic.pm_id == PM_MAGICNO) flipit = 1;
  64.     else flipl( (byte *) &thePic.pm_id);
  65.   }
  66.   if (thePic.pm_id != PM_MAGICNO) return( PMError("not a PM file") );
  67.  
  68.   if (flipit) {
  69.     flipl((byte *) &thePic.pm_np);      flipl((byte *) &thePic.pm_nrow);
  70.     flipl((byte *) &thePic.pm_ncol);    flipl((byte *) &thePic.pm_nband);
  71.     flipl((byte *) &thePic.pm_form);    flipl((byte *) &thePic.pm_cmtsize);
  72.     }
  73.           
  74.   /* make sure that the input picture can be dealt with */
  75.   if ( thePic.pm_nband!=1 || 
  76.       (thePic.pm_form!=PM_I && thePic.pm_form!=PM_C) ||
  77.       (thePic.pm_form==PM_I && thePic.pm_np>1) ||
  78.       (thePic.pm_form==PM_C && (thePic.pm_np==2 || thePic.pm_np>4)) ) {
  79.     fprintf(stderr,"PM picture not in a displayable format.\n");
  80.     fprintf(stderr,"(ie, 1-plane PM_I, or 1-, 3-, or 4-plane PM_C)\n");
  81.     return 1;
  82.     }    
  83.  
  84.   SetDirRButt(F_FORMAT, F_PM);
  85.   if (thePic.pm_form==PM_I || thePic.pm_np>1) 
  86.        SetDirRButt(F_COLORS, F_FULLCOLOR);
  87.   else SetDirRButt(F_COLORS, F_GREYSCALE);
  88.  
  89.   w = thePic.pm_ncol;  h = thePic.pm_nrow;
  90.  
  91.   isize = pm_isize(&thePic);
  92.  
  93.   if (DEBUG) 
  94.     fprintf(stderr,"%s: LoadPM() - loading a %dx%d %s pic, %d planes\n",
  95.         cmd, w, h, (thePic.pm_form==PM_I) ? "PM_I" : "PM_C", 
  96.         thePic.pm_np);
  97.  
  98.   SetISTR(ISTR_FORMAT,"PM, %s.  (%d plane %s)  (%d bytes)",
  99.       (thePic.pm_form==PM_I || thePic.pm_np>1) ? 
  100.          "24-bit color" : "8-bit greyscale",
  101.       thePic.pm_np, (thePic.pm_form==PM_I) ? "PM_I" : "PM_C",
  102.       isize + PM_IOHDR_SIZE + thePic.pm_cmtsize);
  103.  
  104.   sprintf(formatStr, "%dx%d PM.", w,h);
  105.  
  106.   /* allocate memory for picture and read it in */
  107.   thePic.pm_image = (char *) malloc(isize);
  108.   if (thePic.pm_image == NULL) 
  109.     return( PMError("unable to malloc PM picture") );
  110.  
  111.   if (fread(thePic.pm_image, (unsigned) isize, 1, fp) != 1) 
  112.     return( PMError("file read error") );
  113.   if (fp!=stdin) fclose(fp);
  114.  
  115.   if (DEBUG) fprintf(stderr,"loadpm 1\n");
  116.  
  117.   /* convert PM picture to 'pic' (8 bit) format */
  118.   if (thePic.pm_form == PM_I) {
  119.     int  *intptr;
  120.     byte *pic24, *picptr;
  121.  
  122.     if ((pic24 = (byte *) malloc(w*h*3))==NULL) 
  123.       return( PMError("unable to malloc 24-bit picture") );
  124.       
  125.     intptr = (int *) thePic.pm_image;
  126.     picptr = pic24;
  127.  
  128.     if (flipit) {    /* if flipit, integer is RRGGBBAA instead of AABBGGRR */
  129.       for (i=w*h; i>0; i--, intptr++) {
  130.     if ((i & 0x3fff) == 0) WaitCursor();
  131.     *picptr++ = (*intptr>>24) & 0xff;
  132.     *picptr++ = (*intptr>>16) & 0xff;
  133.     *picptr++ = (*intptr>>8)  & 0xff;
  134.       }
  135.     }
  136.     else {
  137.       for (i=w*h; i>0; i--, intptr++) {
  138.     if ((i & 0x3fff) == 0) WaitCursor();
  139.     *picptr++ = (*intptr)     & 0xff;
  140.     *picptr++ = (*intptr>>8)  & 0xff;
  141.     *picptr++ = (*intptr>>16) & 0xff;
  142.       }
  143.     }
  144.  
  145.     if (DEBUG) fprintf(stderr,"loadpm 2\n");
  146.  
  147.     free(thePic.pm_image);
  148.     rv=Conv24to8(pic24,w,h,nc);
  149.     free(pic24);
  150.   }
  151.  
  152.  
  153.   else if (thePic.pm_form == PM_C && thePic.pm_np>1) {
  154.     byte *pic24, *picptr, *rptr, *gptr, *bptr;
  155.  
  156.     if ((pic24 = (byte *) malloc(w*h*3))==NULL) 
  157.       return( PMError("unable to malloc 24-bit picture") );
  158.  
  159.     rptr = (byte *) thePic.pm_image;
  160.     gptr = rptr + w*h;
  161.     bptr = rptr + w*h*2;
  162.     picptr = pic24;
  163.     for (i=w*h; i>0; i--) {
  164.       if ((i & 0x3fff) == 0) WaitCursor();
  165.       *picptr++ = *rptr++;
  166.       *picptr++ = *gptr++;
  167.       *picptr++ = *bptr++;
  168.     }
  169.     free(thePic.pm_image);
  170.     rv=Conv24to8(pic24,w,h,nc);
  171.     free(pic24);
  172.   }
  173.   
  174.   else if (thePic.pm_form == PM_C && thePic.pm_np==1) {
  175.     /* don't have to convert, just point pic at thePic.pm_image */
  176.     pic = (byte *) thePic.pm_image;
  177.     pWIDE = w;  pHIGH = h;  
  178.     for (i=0; i<256; i++) r[i]=g[i]=b[i]=i;  /* and build mono colortable */
  179.     rv = 0;
  180.   }
  181.  
  182.   return rv;
  183. }
  184.  
  185.  
  186. /*******************************************/
  187. int WritePM(fp, pic, w, h, rmap, gmap, bmap, numcols, colorstyle)
  188. FILE *fp;
  189. byte *pic;
  190. int   w,h;
  191. byte *rmap, *gmap, *bmap;
  192. int   numcols, colorstyle;
  193. {
  194.   /* writes a PM file to the already open stream
  195.      'colorstyle' single-handedly determines the type of PM pic written
  196.      if colorstyle==0, (Full Color) a 3-plane PM_C pic is written
  197.      if colorstyle==1, (Greyscal) a 1-plane PM_C pic is written
  198.      if colorstyle==0, (B/W stipple) a 1-plane PM_C pic is written */
  199.  
  200.   char  foo[256];
  201.   int   i;
  202.   byte *p;
  203.  
  204.   /* create 'comment' field */
  205.   sprintf(foo,"created by 'xv %s'\n", namelist[curname]);
  206.  
  207.   /* fill in fields of a pmheader */
  208.   thePic.pm_id = PM_MAGICNO;
  209.   thePic.pm_np = (colorstyle==0) ? 3 : 1;
  210.   thePic.pm_ncol = w;
  211.   thePic.pm_nrow = h;
  212.   thePic.pm_nband = 1;
  213.   thePic.pm_form  = PM_C;
  214.   thePic.pm_cmtsize = strlen(foo);
  215.  
  216.   if (fwrite(&thePic, PM_IOHDR_SIZE, 1, fp) != 1) return -1;
  217.  
  218.   /* write the picture data */
  219.   if (colorstyle == 0) {         /* 24bit RGB, organized as 3 8bit planes */
  220.     for (i=0,p=pic; i<w*h; i++, p++) {
  221.       if ((i & 0x3fff) == 0) WaitCursor();
  222.       putc(rmap[*p], fp);
  223.     }
  224.  
  225.     for (i=0,p=pic; i<w*h; i++, p++) {
  226.       if ((i & 0x3fff) == 0) WaitCursor();
  227.       putc(gmap[*p], fp);
  228.     }
  229.  
  230.     for (i=0,p=pic; i<w*h; i++, p++) {
  231.       if ((i & 0x3fff) == 0) WaitCursor();
  232.       putc(bmap[*p], fp);
  233.     }
  234.   }
  235.  
  236.   else if (colorstyle == 1) {    /* GreyScale: 8 bits per pixel */
  237.     byte rgb[256];
  238.     for (i=0; i<numcols; i++) rgb[i] = MONO(rmap[i],gmap[i],bmap[i]);
  239.     for (i=0, p=pic; i<w*h; i++, p++) {
  240.       if ((i & 0x3fff) == 0) WaitCursor();
  241.       putc(rgb[*p],fp);
  242.     }
  243.   }
  244.  
  245.   else /* (colorstyle == 2) */ { /* B/W stipple.  pic is 1's and 0's */
  246.     for (i=0, p=pic; i<w*h; i++, p++) {
  247.       if ((i & 0x3fff) == 0) WaitCursor();
  248.       putc(*p ? 255 : 0,fp);
  249.     }
  250.   }
  251.  
  252.   if (fputs(foo,fp)==EOF) return -1;
  253.  
  254.   return 0;
  255. }
  256.  
  257.  
  258. /*****************************/
  259. static int PMError(st)
  260. char *st;
  261. {
  262.   SetISTR(ISTR_WARNING,"LoadPM() - %s",cmd,st);
  263.   Warning();
  264.   if (thePic.pm_image != NULL) free(thePic.pm_image);
  265.   return -1;
  266. }
  267.  
  268.  
  269. /*****************************/
  270. static void flipl(p)
  271.      byte *p;
  272. {
  273.   byte t; 
  274.   t = p[0];  p[0]=p[3];  p[3] = t;
  275.   t = p[1];  p[1]=p[2];  p[2] = t;
  276. }
  277.  
  278.  
  279.  
  280.