home *** CD-ROM | disk | FTP | other *** search
/ Resource Library: Multimedia / Resource Library: Multimedia.iso / maestro / source / displytl / xvpm.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-06-15  |  6.9 KB  |  273 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 "xvimage.h"
  35. #include "xvpm.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,"r");
  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.   w = thePic.pm_ncol;  h = thePic.pm_nrow;
  85.  
  86.   isize = pm_isize(&thePic);
  87.  
  88.   if (DEBUG) 
  89.     fprintf(stderr,"%s: LoadPM() - loading a %dx%d %s pic, %d planes\n",
  90.         cmd, w, h, (thePic.pm_form==PM_I) ? "PM_I" : "PM_C", 
  91.         thePic.pm_np);
  92.  
  93.   sprintf(formatStr, "PM, %s.  (%d plane %s)  (%d bytes)",
  94.       (thePic.pm_form==PM_I || thePic.pm_np>1) ? 
  95.          "24-bit color" : "8-bit greyscale",
  96.       thePic.pm_np, (thePic.pm_form==PM_I) ? "PM_I" : "PM_C",
  97.       isize + PM_IOHDR_SIZE + thePic.pm_cmtsize);
  98.  
  99.   /* allocate memory for picture and read it in */
  100.   thePic.pm_image = (char *) malloc(isize);
  101.   if (thePic.pm_image == NULL) 
  102.     return( PMError("unable to malloc PM picture") );
  103.  
  104.   if (fread(thePic.pm_image, (unsigned) isize, 1, fp) != 1) 
  105.     return( PMError("file read error") );
  106.   if (fp!=stdin) fclose(fp);
  107.  
  108.   if (DEBUG) fprintf(stderr,"loadpm 1\n");
  109.  
  110.   /* convert PM picture to 'pic' (8 bit) format */
  111.   if (thePic.pm_form == PM_I) {
  112.     int  *intptr;
  113.     byte *pic24, *picptr;
  114.  
  115.     if ((pic24 = (byte *) malloc(w*h*3))==NULL) 
  116.       return( PMError("unable to malloc 24-bit picture") );
  117.       
  118.     intptr = (int *) thePic.pm_image;
  119.     picptr = pic24;
  120.  
  121.     if (flipit) {    /* if flipit, integer is RRGGBBAA instead of AABBGGRR */
  122.       for (i=w*h; i>0; i--, intptr++) {
  123.     *picptr++ = (*intptr>>24) & 0xff;
  124.     *picptr++ = (*intptr>>16) & 0xff;
  125.     *picptr++ = (*intptr>>8)  & 0xff;
  126.       }
  127.     }
  128.     else {
  129.       for (i=w*h; i>0; i--, intptr++) {
  130.     *picptr++ = (*intptr)     & 0xff;
  131.     *picptr++ = (*intptr>>8)  & 0xff;
  132.     *picptr++ = (*intptr>>16) & 0xff;
  133.       }
  134.     }
  135.  
  136.     if (DEBUG) fprintf(stderr,"loadpm 2\n");
  137.  
  138.     free(thePic.pm_image);
  139.     rv=Conv24to8(pic24,w,h,nc);
  140.     free(pic24);
  141.   }
  142.  
  143.  
  144.   else if (thePic.pm_form == PM_C && thePic.pm_np>1) {
  145.     byte *pic24, *picptr, *rptr, *gptr, *bptr;
  146.  
  147.     if ((pic24 = (byte *) malloc(w*h*3))==NULL) 
  148.       return( PMError("unable to malloc 24-bit picture") );
  149.  
  150.     rptr = (byte *) thePic.pm_image;
  151.     gptr = rptr + w*h;
  152.     bptr = rptr + w*h*2;
  153.     picptr = pic24;
  154.     for (i=w*h; i>0; i--) {
  155.       *picptr++ = *rptr++;
  156.       *picptr++ = *gptr++;
  157.       *picptr++ = *bptr++;
  158.     }
  159.     free(thePic.pm_image);
  160.     rv=Conv24to8(pic24,w,h,nc);
  161.     free(pic24);
  162.   }
  163.   
  164.   else if (thePic.pm_form == PM_C && thePic.pm_np==1) {
  165.     /* don't have to convert, just point pic at thePic.pm_image */
  166.     pic = (byte *) thePic.pm_image;
  167.     pWIDE = w;  pHIGH = h;  
  168.     for (i=0; i<256; i++) r[i]=g[i]=b[i]=i;  /* and build mono colortable */
  169.     rv = 0;
  170.   }
  171.  
  172.   return rv;
  173. }
  174.  
  175.  
  176. /*******************************************/
  177. int WritePM(fp, pic, w, h, rmap, gmap, bmap, numcols, colorstyle)
  178. FILE *fp;
  179. byte *pic;
  180. int   w,h;
  181. byte *rmap, *gmap, *bmap;
  182. int   numcols, colorstyle;
  183. {
  184.   /* writes a PM file to the already open stream
  185.      'colorstyle' single-handedly determines the type of PM pic written
  186.      if colorstyle==0, (Full Color) a 3-plane PM_C pic is written
  187.      if colorstyle==1, (Greyscal) a 1-plane PM_C pic is written
  188.      if colorstyle==0, (B/W stipple) a 1-plane PM_C pic is written */
  189.  
  190.   char  foo[256];
  191.   int   i;
  192.   byte *p;
  193.  
  194.   /* create 'comment' field */
  195.   sprintf(foo,"created by 'xv %s'\n", namelist[curname]);
  196.  
  197.   /* fill in fields of a pmheader */
  198.   thePic.pm_id = PM_MAGICNO;
  199.   thePic.pm_np = (colorstyle==0) ? 3 : 1;
  200.   thePic.pm_ncol = w;
  201.   thePic.pm_nrow = h;
  202.   thePic.pm_nband = 1;
  203.   thePic.pm_form  = PM_C;
  204.   thePic.pm_cmtsize = strlen(foo);
  205.  
  206.   if (fwrite(&thePic, PM_IOHDR_SIZE, 1, fp) != 1) return -1;
  207.  
  208.   /* write the picture data */
  209.   if (colorstyle == 0) {         /* 24bit RGB, organized as 3 8bit planes */
  210.     for (i=0,p=pic; i<w*h; i++, p++) {
  211.       putc(rmap[*p], fp);
  212.     }
  213.  
  214.     for (i=0,p=pic; i<w*h; i++, p++) {
  215.       putc(gmap[*p], fp);
  216.     }
  217.  
  218.     for (i=0,p=pic; i<w*h; i++, p++) {
  219.       putc(bmap[*p], fp);
  220.     }
  221.   }
  222.  
  223.   else if (colorstyle == 1) {    /* GreyScale: 8 bits per pixel */
  224.     byte rgb[256];
  225.     for (i=0; i<numcols; i++) rgb[i] = MONO(rmap[i],gmap[i],bmap[i]);
  226.     for (i=0, p=pic; i<w*h; i++, p++) {
  227.       putc(rgb[*p],fp);
  228.     }
  229.   }
  230.  
  231.   else /* (colorstyle == 2) */ { /* B/W stipple.  pic is 1's and 0's */
  232.     for (i=0, p=pic; i<w*h; i++, p++) {
  233.       putc(*p ? 255 : 0,fp);
  234.     }
  235.   }
  236.  
  237.   if (fputs(foo,fp)==EOF) return -1;
  238.  
  239.   return 0;
  240. }
  241.  
  242.  
  243. /*****************************/
  244. static int PMError(st)
  245. char *st;
  246. {
  247.   printf("LoadPM() - %s\n",cmd,st);
  248.   if (thePic.pm_image != NULL) free(thePic.pm_image);
  249.   return -1;
  250. }
  251.  
  252.  
  253. /*****************************/
  254. static void flipl(p)
  255.      byte *p;
  256. {
  257.   byte t; 
  258.   t = p[0];  p[0]=p[3];  p[3] = t;
  259.   t = p[1];  p[1]=p[2];  p[2] = t;
  260. }
  261.  
  262.  
  263.  
  264.  
  265.  
  266.  
  267.  
  268.  
  269.  
  270.  
  271.  
  272.  
  273.