Logo Search packages:      
Sourcecode: lexmark7000linux version File versions

pnmraw2cmyk.c

/*
 * pnmraw2cmyk.c -- converts RBG image from PNM raw
 *                  to series of dithered CMY(K) PBMraw bitmaps
 *              
 * (C) 1999 Henryk Paluch, released under GNU GPL license, version 2
 * 
 * $Id: pnmraw2cmyk.c,v 1.3 1999/03/28 17:52:49 henryk Exp $
 */

#include<stdlib.h>
#include<stdio.h>
#include<errno.h>
#include<string.h>
#include<unistd.h> /* getopt() */
#include<syslog.h>


#define DIV8(x) ( (x) >> 3 )
#define MOD8(x) ( (x) & 0x7 )

int height;                 /* height of PBM bitmap (lines e.g., pixels) */
int width;                  /* width of line bitmap in pixels) */
int bwidth;                 /* real bitmap width (bytes) */
int obwidth;                /* output bitmap width (bytes) */
int obsize;          /* output bitmap size (bytes) */
int plates;                /* number of color plates (3 or 4) */
unsigned char *lines=NULL; /* this is pixel buffer for one line */
unsigned char *olines=NULL;
static char *fprefix=NULL;
static int mayeof=0;
static int genk=0;

/*  parse_pnm_header() - decodes header of PNM bitmap
 *        sets global vars: height (pixels), 
 *                          bwidth (real bitamp width - bytes)
 *                          width  (memory bitmap width - bytes)
 *        PNMraw is simple RGB bitmap. It consists
 *        of text header and raw data bytes.
 *        Example: P6
 *                 # comment lines
 *                 width height
 *                 255
 *                 raw bytes
 *                 
 *                 width & height is in pixels,
 *                 every pixel is 3 byte value of RGB
 */


int parse_pnm_header(FILE *f)
{
   char buf[1024];
   int tmp;
   
   if (fgets(buf,1023,f)==0  || strncmp(buf,"P6",2)!=0)
   {
      if (mayeof)
       return 0;
      else
      {
        fprintf(stderr,"Illegal pnmraw header"); 
      exit(-1);
      }
   }
   do{
   fgets(buf,1023,f); /* skip comment line(s) */
   }while(buf[0]=='#');

   sscanf(buf,"%d %d\n",&width,&height);
   if (width <=0 || height <=0)
   {
      fprintf(stderr,"Illegal width (%d) or height (%d)\n",width,height);
      exit(-1);
   }
   fgets(buf,64,stdin); // scanf corrupts \n !!!
   bwidth= width*3; /* round width to whole byte */
   fprintf(stderr,"bwidth (bytes): %d (%d pixels), height (lines): %d\n",
       bwidth,width, height);
   return 1;
}



/* read_lines() -- read 'readcount' data lines from PBM bitmap
 *                 to 'lines' -- bitmap in memory
 */

int read_line(FILE *f)
{
   int i,c;

   if (lines==NULL)
      lines=(char*)malloc(bwidth);
   /* zero the buffer */
/*   memset(lines,(char)0,bwidth); */
      c=fread(lines,1,bwidth,f);
      if (c==-1)
      {
       perror("fread");
       exit(-1);
      }
   return c;
}

static void write_pbm_bitmap(FILE *f,unsigned char *buf,char *filename,
      int plate)
{
   char *plnames[4]={"Cyan","Magenta","Yellow","Black"};
   int i;

   fprintf(f,"P4\n");
   fprintf(f,"# dithered separation '%s', %s plate\n",
              filename,plnames[plate]);
   fprintf(f,"%d %d\n",width,height);
   for(i=0;i<height;i++)
   {
      if (fwrite(buf+i*obwidth,1,obwidth,f)!=obwidth)
      {
       fprintf(stderr,"short write\n");
       exit(-1);
      }
   }
}

static void usage(void)
{
   int i;
   fprintf(stderr,"pnmraw2cmyk PBMraw bitmap converter\n");
   fprintf(stderr,"   convert PNMraw RGB bitmap into separate"
                " CMY(K) dithered PBMraw bitmaps\n");

   fprintf(stderr,"Usage: pnmraw2cmyk [ -h ] "
                " < input.pnmraw > output.pbmraw (s)\n");
   fprintf(stderr,"       -h\tthis help text\n");
   fprintf(stderr,"       -o name\toutput to separate CMY(K) files"
                " instead of stdout\n");
   fprintf(stderr,"       -k generate full CMYK instead of CMY\n");
   exit(-1);
}

int main(int argc, char *argv[])
{
   int pagecount=0;
   int c,i;
  
   while( (c=getopt(argc, argv, ":o:hk"))!=-1 )
      switch(c){
       case 'h':
          usage();
          break;
       case 'o':
          fprefix=optarg;
          break;
       case 'k':
          genk=1;
          break;
       default:
          usage();
      }
   
   plates= (genk ? 4 : 3); /* number of color plates: 3 = CMY, 4 = CMYK */

   /* process raw PBM bitmap(s) */
   while(parse_pnm_header(stdin))
   {
      obwidth=(width+7)/8;
      fprintf(stderr,"Output bitmap width (%d bytes)\n",obwidth);
      obsize=obwidth*height;
      fprintf(stderr,"Output bitmap size (%d bytes)\n",obsize);
      
      olines=(unsigned char*)malloc(obsize*plates);
      fprintf(stderr,"Allocated %d bytes for %d bitmaps\n",obsize*plates,
          plates);
      /* now it is time to dither */
      for(i=0;i<height;i++)
      {
       if (read_line(stdin)!=bwidth)
       {
          fprintf(stderr,"short read\n");
          exit(-1);
       }
       dither_cmyk(lines, /* input row */
                   i,      /* row number */
                 width,  /* width of source in pixels */
                 width,  /* width of dest in pixels */
                 olines+0*obsize+obwidth*i, /* cyan outbuf */
                 olines+1*obsize+obwidth*i, /* magenta outbuf */
                 olines+2*obsize+obwidth*i, /* yellow outbuf */
                 (genk ?                    /* black outbuf */
                  olines+3*obsize+obwidth*i
                  : NULL ));
      }
      if (fprefix!=NULL)
      {
       char pnames[]="cmyk";
       FILE *ff;
       int y;
       char buf[1024];
       for(y=0;y<plates;y++)
       {
          snprintf(buf,1023,"%s%c-%03d.pbm",fprefix,pnames[y],pagecount);
          if ( (ff=fopen(buf,"w+"))==NULL)
          {
             fprintf(stderr,"fopen '%s'",buf);
             perror("");
             exit(-1);
          }
          write_pbm_bitmap(ff,olines+y*obsize,buf,y);
          fclose(ff);
       }
      }
      else
      {
       int y;
       for(y=0;y<plates;y++)
          write_pbm_bitmap(stdout,olines+y*obsize,"(stdout)",y);
      }
      pagecount++;
      mayeof=1;
      if (lines!=NULL)
      {
       free(lines);
       lines=NULL;
      }
      if (olines!=NULL)
      {
       free(olines);
       olines=NULL;
      }
   }

   return 0;
}

Generated by  Doxygen 1.6.0   Back to index