Beispiel #1
0
/*{{{  static void prtX360(int pno)*/
static void prtX360(int pno)
{
  bit** bits;
  bit* pr[24];
  int row, v_sp;
  int i;

  v_sp = 0;

  printf("\033U\001");             /* print unidirectional */
  bits = pbm_allocarray(cols, 48);

  for (row=0; row<rows; row+=48)
  {
    for(i=0; i<48 && row+i<rows; i++)
      readpbmrow(fp, bits[i], cols, format);

    while(i<48)
      memset(bits[i++], PBM_WHITE, cols);

    for(i=0; i<24; i++)
      pr[i]=bits[2*i];
    
    print24rows(pno, pr, &v_sp);   /* even rows */
    v_sp += 1;      /* vertical space : 1/360 */
    
    for(i=0; i<24; i++)
      pr[i]=bits[2*i+1];
    
    print24rows(pno, pr, &v_sp);   /* odd rows */

    v_sp += 47;       /* vertical space : 47/360 */
  }
  putchar('\f');
}
Beispiel #2
0
/*{{{  static void epsX216(int pno)*/
static void epsX216(int pno)
{
  bit** bits;
  bit* pr[8];
  int row, v_sp;
  int i, j;

  v_sp = 0;   /* counter for vertical spacing */

  bits = pbm_allocarray(cols, 24);
                            
  for (row=0; row<rows; row+=24)
  {
    for(i=0; i<24 && row+i<rows; i++)
      readpbmrow(fp, bits[i], cols, format);

    while(i<24)
      memset(bits[i++], PBM_WHITE, cols); /* remaining rows set to 'white' */

    for(j=0; j<3; j++)
    {
      for(i=0; i<8; i++)
        pr[i]=bits[3*i+j];

      print8rows(pno, pr, &v_sp);
      v_sp += 1;
    }
    v_sp += 21;
  }
  putchar('\f');
}
Beispiel #3
0
/*{{{  static void prtX180(int pno)*/
static void prtX180(int pno)
{
  bit** bits;
  bit* pr[24];             /* Print Row */
  int row, v_sp;
  int i;
  
  v_sp = 0;

  printf("\033U\001");             /* print unidirectional */
  bits = pbm_allocarray(cols, 24);

  for (row=0; row<rows; row+=24)
  {
    for(i=0; i<24 && row+i<rows; i++)
      readpbmrow(fp, bits[i], cols, format);

    while(i<24)
      memset(bits[i++], PBM_WHITE, cols);

    for(i=0; i<24; i++)      /* senseless ? yes ! */
      pr[i]=bits[i];

    print24rows(pno, pr, &v_sp);

    v_sp += 24;           /* vertical space : 24/180 */
  }
  putchar('\f');
}
Beispiel #4
0
/*{{{  static void epsX144(int pno)*/
static void epsX144(int pno)
{
  bit** bits;
  bit* pr[8];
  int row, v_sp;
  int i, j;

  v_sp = 0;   /* counter for vertical spacing */

  bits = pbm_allocarray(cols, 16);
                            
  for (row=0; row<rows; row+=16)
  {
    for(i=0; i<16 && row+i<rows; i++)
      readpbmrow(fp, bits[i], cols, format);
    while(i<16)
      memset(bits[i++], PBM_WHITE, cols);

    for(j=0; j<2; j++)
    {
      for(i=0; i<8; i++)
        pr[i]=bits[2*i+j];

      print8rows(pno, pr, &v_sp);
      v_sp += 1;
    }
    v_sp += 22;
  }
  putchar('\f');
}
Beispiel #5
0
/*{{{  static void epsX72(int pno)*/
static void epsX72(int pno)
{
  bit** bits;
  bit* pr[8];             /* Print Row */
  int row, v_sp;
  int i;
  
  v_sp = 0;

  bits = pbm_allocarray(cols, 8);
  
  for (row=0; row<rows; row+=8)
  {
    for(i=0; i<8 && row+i<rows; i++)
      readpbmrow(fp, bits[i], cols, format);
    while(i<8)
      memset(bits[i++], PBM_WHITE, cols);

    for(i=0; i<8; i++)  /* Not very useful in this case */
      pr[i]=bits[i];

    print8rows(pno, pr, &v_sp);

    v_sp += 24;
  }
  putchar('\f');
}
Beispiel #6
0
int 
main (int argc, char *args[])
{
  int i, n, r, c, ch;
  FILE *inf;
  marklistptr library = NULL, list = NULL, step = NULL;
  marklistptr symbol_list = NULL;
  marktype d, d2;
  Pixel **bitmap, **recon, **bitmapcopy;
  char *splitfilename = NULL;
  int cols, rows, count, librarysize, lossy = 1;
  int quick = 0;
  int ticencode = 0, ticdecode = 0, external = 0;
  char *libraryname = NULL, *infile = NULL;
  char *s1 = NULL, *s2 = NULL;
  char bufferin[BUFSIZ], bufferout[BUFSIZ];

  if (argc < 2)
    usage ();

  while ((ch = getopt (argc, args, "edlLQhvXR:")) != -1)
    switch (ch)
      {
      case 'e':
	ticencode = 1;
	break;
      case 'd':
	ticdecode = 1;
	break;
      case 'l':
	lossy = 1;
	break;
      case 'L':
	lossy = 0;
	break;
      case 'Q':
	quick = 1;
	break;
      case 'v':
	V = 1;
	break;
      case 'X':
	external = 1;
	break;
      case 'R':
	splitfilename = optarg;
	break;
      case 'h':
      case '?':
	usage ();
      }

  for (i = 1; i < argc; i++)
    if (args[i][0] != '-')
      if (strcmp (args[i - 1], "-R"))
	{			/* ignore arg following -R, ie. -R <filename> */
	  if (!s1)
	    s1 = args[i];
	  else if (!s2)
	    s2 = args[i];
	  else
	    error_msg (args[0], "too many filenames", "");
	}

  if (ticencode == ticdecode)
    error_msg (args[0], "please specify either encode XOR decode", "");

  if (ticencode)
    {
	  /*****************
	    ENCODING STAGE
	  *****************/
      long PrevBits = 0;
      long BITS_header = 0, BITS_symbols = 0, BITS_offsets = 0, BITS_residue = 0,
        BITS_footer = 0, BITS_library = 0;

      libraryname = s1;
      if (!libraryname)
	error_msg (args[0], "please specify a library file", "");
      infile = s2;
      if (!infile)
	error_msg (args[0], "please specify a file name", "");

      inf = fopen (infile, "rb");
      if (inf == NULL)
	error_msg (args[0], "Trouble opening file:", infile);
      setbuf (inf, bufferin);

      count = librarysize = read_library (libraryname, &library);

      if (V)
	fprintf (stderr, "%s: processing...\n", args[0]);

      if (pbm_isapbmfile (inf))
	{
	  if (V)
	    fprintf (stderr, "reading file %s...\n", infile);
	  bitmap = pbm_readfile (inf, &cols, &rows);
	  fclose (inf);

	  bitmapcopy = pbm_copy (bitmap, cols, rows);

	  if (V)
	    fprintf (stderr, "extracting...");
	  ExtractAllMarks (bitmap, &list, cols, rows);
	  if (V)
	    fprintf (stderr, "(%d marks)\n", marklist_length (list));

	  /* sort into reading order */
	  if (V)
	    fprintf (stderr, "sorting...\n");
	  list = sortmarks (list);

	  pbm_freearray (&bitmap, rows);	/* clear old version */
	  bitmap = bitmapcopy;	/* point to the copy */
	  recon = pbm_allocarray (cols, rows);

	  if (V)
	    fprintf (stderr, "matching...");

	  match_sequence (list, library, &symbol_list, recon, quick);


	  PrevBits = 0;
	  setbuf (stdout, bufferout);
	  /* start output */
	  magic_write (stdout, MAGIC_TIC);
	  InitArithEncoding ();

	  EncodeGammaDist (1);	/* version 1 of the program */
	  EncodeGammaDist (lossy);	/* lossy=1 = no residue */
	  EncodeGammaDist (external);	/* 1== external file */

	  count = marklist_length (symbol_list);
	  if (V)
	    fprintf (stderr, "encoding cols, rows, and number of symbols=%d\n", count);

	  EncodeGammaDist (cols);
	  EncodeGammaDist (rows);
	  EncodeGammaDist (count);
	  EncodeGammaDist (librarysize);

	  BITS_header = CountOfBitsOut - PrevBits;
	  PrevBits = CountOfBitsOut;


	  /* output the library sequence */
	  if (external == 0)
	    {
	      if (V)
		fprintf (stderr, "encoding library\n");

	      bl_clearmodel ();
	      bl_writetemplate (library_template);
	      for (step = library; step; step = step->next)
		bl_compress_mark (step->data);
	      bl_freemodel ();
	      BITS_library = CountOfBitsOut - PrevBits;
	      PrevBits = CountOfBitsOut;
	    }

	  /* output the symbol sequence */
	  if (V)
	    fprintf (stderr, "encoding symbol sequence\n");
	  InitPPM ();
	  EncodeSymbols (symbol_list, count);
	  BITS_symbols = CountOfBitsOut - PrevBits;
	  PrevBits = CountOfBitsOut;


	  /* output the offset sequence */
	  if (V)
	    fprintf (stderr, "encoding offset sequence\n");
	  EncodeOffsets (symbol_list, count);
	  BITS_offsets = CountOfBitsOut - PrevBits;
	  PrevBits = CountOfBitsOut;

	  EncodeChecksum ();	/* code lossy checksum */

	  /* calculate the residue...and compress it---if need be! */
	  if (!lossy)
	    {
	      if (V)
		fprintf (stderr, "encoding residue...\n");

	      d.bitmap = bitmap;
	      d.h = rows;
	      d.w = cols;
	      d2.bitmap = recon;
	      d2.h = rows;
	      d2.w = cols;

	      if (splitfilename)
		{
		  FILE *temp;

		  CloseDownArithEncoding ();
		  fclose (stdout);
		  /* no residue result */
		  BITS_footer = CountOfBitsOut - PrevBits;

		  temp = fopen (splitfilename, "wb");
		  if (temp == NULL)
		    error_msg (args[0], "Trouble creating file:", splitfilename);

		  arith_out = temp;
		  InitArithEncoding ();
		  bl_clair_compress (d, d2);
		  CloseDownArithEncoding ();
		  BITS_residue = CountOfBitsOut;
		  fclose (temp);
		}
	      else
		{
		  bl_clair_compress (d, d2);
		  BITS_residue = CountOfBitsOut - PrevBits;
		  PrevBits = CountOfBitsOut;
		  EncodeChecksum ();	/* code lossless checksum */
		  CloseDownArithEncoding ();
		  BITS_footer = CountOfBitsOut - PrevBits;
		}
	    }
	  else
	    {
	      if (V)
		fprintf (stderr, "not encoding residue..lossy mode\n");
	      CloseDownArithEncoding ();
	      BITS_footer = CountOfBitsOut - PrevBits;
	    }

	  /* because we edit the values above */
	  CountOfBitsOut = BITS_header + BITS_library + BITS_symbols + BITS_offsets + BITS_residue + BITS_footer;

	  fprintf (stderr, "bits: header=%ld, library=%ld, "
		   "symbols=%ld, offsets=%ld, residue=%ld, footer=%ld\n",
		   BITS_header, BITS_library, BITS_symbols,
		   BITS_offsets, BITS_residue, BITS_footer);
	  fprintf (stderr, "total bits: %ld, ", CountOfBitsOut);
	  fprintf (stderr, "Lossy CR: %4.2f", (cols * rows) / (float) (CountOfBitsOut - BITS_residue));
	  if (external)
	    fprintf (stderr, " (excluding external lib)");
	  fprintf (stderr, ", Lossless CR: %4.2f\n", (!lossy) * (cols * rows) / (float) (CountOfBitsOut));
	}
      else
	error_msg (args[0], "unknown format of bitmap--expecting PBM.", "");
    }
  else
    {
	  /*****************
	    DECODING STAGE
	  *****************/
      int lastx, lasty;
      librarysize = 0;

      if (external)
	{
	  libraryname = s1;
	  infile = s2;
	  count = librarysize = read_library (libraryname, &library);
	}
      else
	{
	  infile = s1;
	  if (infile && s2)
	    error_msg (args[0], "too many filenames", "");
	}

      if (!freopen (infile, "rb", stdin))
	error_msg (args[0], "Trouble opening file:", infile);


      if (V)
	fprintf (stderr, "decompressing...\n");

      setbuf (stdin, bufferin);
      magic_check (stdin, MAGIC_TIC);

      InitArithDecoding ();

      {
	int version = DecodeGammaDist ();
	if (version != 1)
	  error_msg (args[0], "Need later version of decompressor.", "");
      }

      {
	int templossy = DecodeGammaDist ();
	if (!lossy)
	  lossy = templossy;	/* can only choose if encoded file is lossless */
	if (V)
	  {
	    if (lossy)
	      fprintf (stderr, "lossy mode\n");
	    else
	      fprintf (stderr, "lossless mode\n");
	  }
      }

      if (DecodeGammaDist ())
	{			/* if compressed file doesn't contain library */
	  if (!external)
	    error_msg (args[0], "compressed file doesn't contain library, specify externally", "");
	  external = 1;
	}
      else
	{			/* if compressed file contains library */
	  if (external)
	    fprintf (stderr, "ignoring external library file\n");
	  external = 0;
	}

      cols = DecodeGammaDist ();
      rows = DecodeGammaDist ();
      count = DecodeGammaDist ();

      i = DecodeGammaDist ();	/* librarysize */
      if (external)
	{
	  if (i > librarysize)
	    error_msg (args[0], "external library file is too small!", "");
	  else if (i < librarysize)
	    fprintf (stderr, "%s: warning, expecting a different (smaller) library.\n", args[0]);
	}
      librarysize = i;

      if (V)
	fprintf (stderr, "cols %d, rows %d, num syms %d, library size %d\n", cols, rows, count, librarysize);

      /* decode library */
      if (external == 0)
	{
	  if (V)
	    fprintf (stderr, "reading library\n");
	  bl_clearmodel ();
	  bl_readtemplate ();
	  for (n = 0; n < librarysize; n++)
	    {
	      bl_decompress_mark (&d);
	      d.symnum = n;
	      if (library == NULL)
		step = marklist_add (&library, d);
	      else
		step = marklist_add (&step, d);
	    }
	  bl_freemodel ();
	  if (V)
	    fprintf (stderr, "read %d marks from library\n", marklist_length (library));
	}

      recon = pbm_allocarray (cols, rows);

      /* decode symbols */
      InitPPM ();
      if (V)
	fprintf (stderr, "decompressing %d symbols\n", count);
      symbol_list = DecodeSymbols (count);

      /* decode offsets */
      if (V)
	fprintf (stderr, "reading offsets...\n");
      DecodeOffsets (symbol_list, count);
      lastx = lasty = 0;
      for (step = symbol_list; step; step = step->next)
	{
	  lastx = lastx + step->data.xoffset;
	  lasty = lasty + step->data.yoffset;

	  marklist_getat (library, step->data.symnum, &d2);
	  for (r = 0; r < d2.h; r++)
	    for (c = 0; c < d2.w; c++)
	      if (pbm_getpixel (d2.bitmap, c, r))
		pbm_putpixel_trunc (recon, lastx + c, lasty + r, 1, cols, rows);	/* we don't care, already warned them! */
	  lastx += d2.w;
	}

      DecodeChecksum (args[0]);

      /* decode the residue */
      if (!lossy)
	{
	  if (V)
	    fprintf (stderr, "decoding residue...\n");

	  bitmap = pbm_allocarray (cols, rows);
	  d.bitmap = bitmap;
	  d.w = d2.w = cols;
	  d.h = d2.h = rows;

	  d2.bitmap = recon;

	  /* NOTE: the 2nd argument is clairvoyantly compressed */
	  if (splitfilename)
	    {
	      FILE *temp;

	      CloseDownArithDecoding ();
	      fclose (stdin);

	      temp = fopen (splitfilename, "rb");
	      if (temp == NULL)
		error_msg (args[0], "Trouble opening file:", splitfilename);

	      arith_in = temp;
	      InitArithDecoding ();
	      bl_clair_decompress (d, d2);
	      CloseDownArithDecoding ();
	      fclose (temp);
	    }
	  else
	    {
	      bl_clair_decompress (d, d2);
	      DecodeChecksum (args[0]);
	      CloseDownArithDecoding ();
	    }
	  pbm_freearray (&recon, rows);
	  recon = bitmap;	/* point to the bitmap */
	}
      else
	{
	  CloseDownArithDecoding ();
	}

      if (V)
	fprintf (stderr, "writing pbm file...\n");
      setbuf (stdout, bufferout);
      pbm_writefile (stdout, recon, cols, rows);
      pbm_freearray (&recon, rows);
    }				/* end decoding */
  exit(0);
}
Beispiel #7
0
int 
main(int argc, char **argv) {
    int n, optstop = 0;
    char *fname = NULL;

    pbm_init(&argc, argv);

    /* Parse options */

    for (n = 1; n < argc; ++n) {
        if (argv[n][0] == '-' && !optstop) {   
            if (argv[n][1] == 'a' || argv[n][1] == 'A') bAscii = 1;
            if (argv[n][1] == 'd' || argv[n][1] == 'D') bScale = 1;
            if (argv[n][1] == 'i' || argv[n][1] == 'I') bInvert = 1;
            if (argv[n][1] == 'h' || argv[n][1] == 'H') usage(argv[0]);
            if (argv[n][1] == '-' && argv[n][2] == 0 && !fname) {
                /* "--" */
                optstop = 1;
            }
            if (argv[n][1] == '-' && (argv[n][2] == 'h' || argv[n][2] == 'H'))
                usage(argv[0]);
        }
        else if (argv[n][0] && !fname) {
            /* Filename */
            fname = argv[n];
        }
    }

    if (fname) 
        infile = pm_openr(fname);
    else
        infile = stdin;

    /* Read MDA file header */

    if (fread(header, 1, 128, infile) < 128)
        pm_error("Not a .MDA file\n");

    if (strncmp((char*) header, ".MDA", 4) && 
        strncmp((char*) header, ".MDP", 4))
        pm_error("Not a .MDA file\n");

    {
        short yy;
        pm_readlittleshort(infile, &yy); nInRows = yy;
        pm_readlittleshort(infile, &yy); nInCols = yy;
    }
    
    overflow2(nOutCols, 8);
    nOutCols = 8 * nInCols;
    nOutRows = nInRows;
    if (bScale) {
        overflow2(nOutRows, 2);
        nOutRows *= 2;
    }

    data = pbm_allocarray(nOutCols, nOutRows);
    
    MALLOCARRAY_NOFAIL(mdrow, nInCols);

    if (header[21] == '0') 
        md2_trans();
    else
        md3_trans();

    pbm_writepbm(stdout, data, nInCols*8, nOutRows, bAscii);

    if (infile != stdin) 
        pm_close(infile);
    fflush(stdout);
    pbm_freearray(data, nOutRows);
    free(mdrow);

    return 0;
}
Beispiel #8
0
int
main(int argc, const char *argv[]) {

    struct cmdlineInfo cmdline;
    bit ** bits;
    unsigned int rows, cols;
    struct font * fontP;
    unsigned int vmargin, hmargin;
    struct text inputText;
    struct text formattedText;
    int maxleftb;

    pm_proginit(&argc, argv);

    parseCommandLine(argc, argv, &cmdline);
    
    computeFont(cmdline, &fontP);

    getText(cmdline.text, fontP, &inputText);
       
    if (cmdline.nomargins) {
        vmargin = 0;
        hmargin = 0;
    } else {
        if (inputText.lineCount == 1) {
            vmargin = fontP->maxheight / 2;
            hmargin = fontP->maxwidth;
        } else {
            vmargin = fontP->maxheight;
            hmargin = 2 * fontP->maxwidth;
        }
    }
    
    if (cmdline.width > 0) {
        if (cmdline.width > INT_MAX -10)
            pm_error("-width value too large: %u", cmdline.width);
            
        /* Flow or truncate lines to meet user's width request */
        if (inputText.lineCount == 1) 
            flowText(inputText, cmdline.width, fontP, cmdline.space,
                     &formattedText);
        else
            truncateText(inputText, cmdline.width, fontP, cmdline.space,
                         &formattedText);
        freeTextArray(inputText);
    } else
        formattedText = inputText;
        
    if (formattedText.lineCount == 0)
        pm_error("No input text.");
    
    computeImageHeight(formattedText, fontP, cmdline.lspace, vmargin,
                       &rows);

    computeImageWidth(formattedText, fontP, cmdline.space, hmargin,
                      &cols, &maxleftb);

    if (cols == 0 || rows == 0)
        pm_error("Input is all whitespace and/or non-renderable characters.");

    bits = pbm_allocarray(cols, rows);

    /* Fill background with white */
    fill_rect(bits, 0, 0, rows, cols, PBM_WHITE);

    /* Put the text in  */
    insert_characters(bits, formattedText, fontP, vmargin, hmargin + maxleftb, 
                      cmdline.space, cmdline.lspace);

    pbm_writepbm(stdout, bits, cols, rows, 0);

    pbm_freearray(bits, rows);

    freeTextArray(formattedText);
    pm_close(stdout);

    return 0;
}
static void
pgmHist(FILE *       const ifP,
        int          const cols,
        int          const rows,
        xelval       const maxval,
        int          const format,
        bool         const dots,
        bool         const no_white,
        bool         const no_black,
        bool         const verbose,
        xelval       const startval,
        xelval       const endval,
        unsigned int const histWidth,
        unsigned int const histHeight,
        bool         const clipSpec,
        unsigned int const clipCount) {

    gray * grayrow;
    bit ** bits;
    int i, j;
    unsigned int * ghist;
    double vscale;
    unsigned int hmax;
    
    MALLOCARRAY(ghist, histWidth);
    if (ghist == NULL)
        pm_error("Not enough memory for histogram array (%u bytes)",
                 histWidth * (unsigned)sizeof(int));
    bits = pbm_allocarray(histWidth, histHeight);
    if (bits == NULL)
        pm_error("no space for output array (%u bits)",
                 histWidth * histHeight);
    memset(ghist, 0, histWidth * sizeof(ghist[0]));

    /* read the pixel values into the histogram arrays */
    grayrow = pgm_allocrow(cols);

    if (verbose)
        pm_message("making histogram...");

    for (i = rows; i > 0; --i) {
        pgm_readpgmrow (ifP, grayrow, cols, maxval, format);
        for (j = cols-1; j >= 0; --j)
            countComp(grayrow[j], startval, endval, histWidth, ghist);
    }
    pgm_freerow(grayrow);

    /* find the highest-valued slot and set the vertical scale value */
    if (verbose)
        pm_message("finding max. slot height...");
    if (clipSpec)
        hmax = clipCount;
    else 
        hmax = maxSlotCount(ghist, histWidth, no_white, no_black);

    assert(hmax > 0);

    if (verbose)
        pm_message("Done: height = %u", hmax);

    clipHistogram(ghist, histWidth, hmax);

    vscale = (double) histHeight / hmax;

    for (i = 0; i < histWidth; ++i) {
        int mark = histHeight - (int)(vscale * ghist[i]);
        for (j = 0; j < mark; ++j)
            bits[j][i] = PBM_BLACK;
        if (j < histHeight)
            bits[j++][i] = PBM_WHITE;
        for ( ; j < histHeight; ++j)
            bits[j][i] = dots ? PBM_BLACK : PBM_WHITE;
    }

    pbm_writepbm(stdout, bits, histWidth, histHeight, 0);
}
/** Generate a mask image (pbm)  */
QString GeoImage::mask(float west, float north, float east, float south,
                       int id, QString prefixDir, QString fname)
{

#define GenMaskBlockStorage(T) \
{ \
	T* iptr; \
	bit *optr; \
	int x,y; \
	for (y = 0; y < dy; y++) { \
	  if (y<-ry1 || y>=rows_-ry1) iptr=0; \
	  else iptr = ((T*)data_p)+(y + ry1)*cols_+rx1; \
	 	optr = dat_b_out[y]; \
	  for (x = 0; x < dx; x++) { \
	    if (!iptr || x<-rx1 || x>=cols_-rx1) *optr=0; \
	  	else *optr=(*iptr==(T)id?1:0); \
	   	optr ++; \
	    if (iptr) iptr ++; \
	  } \
	} \
}

#define GenMaskRowStorage(T) \
{ \
	T* iptr; \
	bit *optr; \
	int x,y; \
	for (y = 0; y < dy; y++) { \
	  if (y<-ry1 || y>=rows_-ry1) iptr=0; \
	  else iptr = (((T**)data_p)[y + ry1]) + rx1; \
	 	optr = dat_b_out[y]; \
	  for (x = 0; x < dx; x++) { \
	    if (!iptr || x<-rx1 || x>=cols_-rx1) *optr=0; \
	  	else *optr=(*iptr==(T)id?1:0); \
	   	optr ++; \
	    if (iptr) iptr ++; \
	  } \
	} \
}

  if (fname.isEmpty()) {        //create output filname
    Q_ASSERT(contains("key"));
    QString dir = CleanUp::mkdir(CleanUp::getTmpDirPID(), prefixDir);
    fname.sprintf("%s/%f_%f_%f_%f.pbm", 
		  dir.toLatin1().constData(),
                  west, north, east, south);
  }
  qDebug("#  GeoImage::mask %s (%f, %f, %f, %f)", fname.toLatin1().constData(),
         west, north, east, south);
  QFile f(fname);
  if (f.exists())
    return fname;

  const void *data_p = data();        //get pointer to data
  Q_ASSERT(data_p);
  if (type_ == UNKNOWN)
    return 0;
  int dx, dy, rx1, ry1, rx2, ry2;
  picBBox(west, north, east, south, rx1, ry2, rx2, ry1);
  dx = rx2 - rx1 + 1;
  dy = ry2 - ry1 + 1;
  if (dx <= 0 || dy <= 0)
    qDebug("#  (ERROR) GeoImage::part: (dx=%d=%d-%d || dy=%d=%d-%d)", dx, rx2,
           rx1, dy, ry2, ry1);

  FILE *of = fopen(fname.toLatin1().constData(), "w");
  if (!of) {
    fprintf(stderr, "#  (ERROR) Can't open file %s for writing!\n",
            fname.toLatin1().constData());
    return "";
  }

  bit **dat_b_out = pbm_allocarray(dx, dy);
  switch (type_) {
  case PFM_FLOAT:
    GenMaskBlockStorage(float);
    break;
  case PFM_UINT:
    GenMaskBlockStorage(unsigned int);
    break;
  case PFM_SINT:
    GenMaskBlockStorage(signed int);
    break;
  case PFM_UINT16:
    GenMaskBlockStorage(unsigned short);
    break;
  case PFM_SINT16:
    GenMaskBlockStorage(signed short);
    break;
  case PBM:{
      bit *iptr;
      bit *optr;
      int x, y;
      for (y = 0; y < dy; y++) {
        iptr = (((bit **) data_p)[y + ry1]) + rx1;
        optr = dat_b_out[y];
        for (x = 0; x < dx; x++) {
          *optr = (*iptr == (bit) id ? 1 : 0);
          optr++;
          iptr++;
        }
      }
    }
//              GenMaskRowStorage(bit);
    break;
  case PFM_BYTE:
    GenMaskBlockStorage(unsigned char);
    break;
  default:
    pbm_freearray(dat_b_out, dy);
    fclose(of);
    return "";
    break;
  }
  pbm_writepbm(of, (bit **) dat_b_out, dx, dy, 0);
  pbm_freearray(dat_b_out, dy);

  fclose(of);
  return fname;
#undef GenMaskBlockStorage
#undef GenMaskRowStorage
}
/** write a scrap of the data,
  * return the filename,
  * if the file exist do nothing
  * argument fname is optional
  * the coordinates of the image part are geodata e.g. Gauss Krueger **/
QString
  GeoImage::part(float west, float north, float east, float south,
                 QString fname)
{
  if (fname.isEmpty()) {        //create output filname
    Q_ASSERT(contains("key"));
    QString dir = CleanUp::getTmpDir();
    fname.sprintf("%s/%s_%f_%f_%f_%f", 
		  dir.toLatin1().constData(), 
		  value("key").toLatin1().constData(),
                  west, north, east, south);
  }
  qDebug("#  GeoImage::part %s (%f, %f, %f, %f)", 
	 fname.toLatin1().constData(), west,
         north, east, south);
  QFile f(fname);
  if (f.exists())
    return fname;

  const void *data_p = data();        //get pointer to data
  Q_ASSERT(data_p);
  if (type_ == UNKNOWN)
    return 0;
  int dx, dy, i, j, rx1, ry1, rx2, ry2;
  picBBox(west, north, east, south, rx1, ry2, rx2, ry1);
  dx = rx2 - rx1 + 1;
  dy = ry2 - ry1 + 1;
  if (dx <= 0 || dy <= 0) {
    qDebug("#  (ERROR) GeoImage::part: (dx=%d=%d-%d || dy=%d=%d-%d)", dx, rx2,
           rx1, dy, ry2, ry1);
    throw ImageException(rx1,rx2,dx,ry1,ry2,dy); 
  }

  FILE *of = fopen(fname.toLatin1().constData(), "w");
  if (!of) {
    throw FileIOException(FileIOException::OPEN_FAILED,fname);
  }

  switch (type_) {
  case PBM:{
      bit *bpi, *bpo, **dat_b_out = pbm_allocarray(dx, dy);
      bit **dat_b = (bit **) data_p;
      for (i = 0; i < dy; i++) {
        bpi = dat_b[i + ry1] + rx1;
        bpo = dat_b_out[i];
        for (j = 0; j < dx; j++) {
          *bpo = *bpi;
          bpo++;
          bpi++;
        }
      }
      pbm_writepbm(of, (bit **) dat_b_out, dx, dy, 0);
      pbm_freearray(dat_b_out, dy);
    }
    break;
  case PGM:{
      gray *gpi, *gpo, **dat_g_out = pgm_allocarray(dx, dy);
      gray **dat_g = (gray **) data_p;
      gray maxval = 0;
      for (i = 0; i < dy; i++) {
        gpi = dat_g[i + ry1] + rx1;
        gpo = dat_g_out[i];
        for (j = 0; j < dx; j++) {
          *gpo = *gpi;
          if (*gpi > maxval)
            maxval = *gpi;
          gpo++;
          gpi++;
        }
      }
      pgm_writepgm(of, (gray **) dat_g_out, dx, dy, maxval, 0);
      pgm_freearray(dat_g_out, dy);
    }
    break;
  case PPM:{
      pixel *ppi, *ppo, **dat_p_out = ppm_allocarray(dx, dy);
      pixel **dat_p = (pixel **) data_p;
      pixval maxval = 255;      //! should be calculated
      for (i = 0; i < dy; i++) {
        ppi = dat_p[i + ry1] + rx1;
        ppo = dat_p_out[i];
        for (j = 0; j < dx; j++) {
          *ppo = *ppi;
          ppo++;
          ppi++;
        }
      }
      ppm_writeppm(of, (pixel **) dat_p_out, dx, dy, maxval, 0);
      ppm_freearray(dat_p_out, dy);
    }
    break;
  default:
    pfm_geo_set(geoWest(),geoNorth(),geoEast(),geoSouth());
    pfm_writepfm_region_type(of, data_, cols_, rows_, minval_, maxval_,
                             rx1, ry1, rx2, ry2, type_);
    break;
  }
  fclose(of);
  return fname;
}
/** Generate a mask image (pbm)  */
QString GeoImage::mask(float west, float north, float east, float south,
                       int id, QString prefixDir, QString fname)
{

#define GenMaskBlockStorage(T) \
{ \
	T* iptr; \
	bit *optr; \
	int x,y; \
	for (y = 0; y < dy; y++) { \
	  if (y<-ry1 || y>=rows_-ry1) iptr=0; \
	  else iptr = ((T*)data_p)+(y + ry1)*cols_+rx1; \
	 	optr = dat_b_out[y]; \
	  for (x = 0; x < dx; x++) { \
	    if (!iptr || x<-rx1 || x>=cols_-rx1) *optr=0; \
	  	else *optr=(*iptr==(T)id?1:0); \
	   	optr ++; \
	    if (iptr) iptr ++; \
	  } \
	} \
}

#define GenMaskRowStorage(T) \
{ \
	T* iptr; \
	bit *optr; \
	int x,y; \
	for (y = 0; y < dy; y++) { \
	  if (y<-ry1 || y>=rows_-ry1) iptr=0; \
	  else iptr = (((T**)data_p)[y + ry1]) + rx1; \
	 	optr = dat_b_out[y]; \
	  for (x = 0; x < dx; x++) { \
	    if (!iptr || x<-rx1 || x>=cols_-rx1) *optr=0; \
	  	else *optr=(*iptr==(T)id?1:0); \
	   	optr ++; \
	    if (iptr) iptr ++; \
	  } \
	} \
}

  if (fname.isEmpty()) {        //create output filname
    Q_ASSERT(contains("key"));
    QString dir = CleanUp::mkdir(CleanUp::getTmpDirPID(), prefixDir);
    fname.sprintf("%s/%f_%f_%f_%f.pbm", 
		  dir.toLatin1().constData(),
                  west, north, east, south);
    qDebug("GeoImage::mask: create output filename %s",fname.toLatin1().constData());
  }
  qDebug("#  GeoImage::mask %s (%f, %f, %f, %f)", fname.toLatin1().constData(),
         west, north, east, south);
  QFile f(fname);
  if (f.exists()) {
    qDebug("mask %s already exists",fname.toLatin1().constData());
    return fname;
  }  

  const void *data_p = data();        //get pointer to data
  Q_ASSERT(data_p);
  if (type_ == UNKNOWN)
    throw ImageException(ImageException::UnknownType,  filename(),
			 __FILE__":GeoImage::mask", __LINE__);
  int dx, dy, rx1, ry1, rx2, ry2;
  picBBox(west, north, east, south, rx1, ry2, rx2, ry1);
  qDebug("GeoImage::mask: picBBox: (%f, %f, %f, %f) (rx1=%d, ry2=%d, rx2=%d, ry1=%d",
	 west, north, east, south, rx1, ry2, rx2, ry1);
  dx = rx2 - rx1 + 1;
  dy = ry2 - ry1 + 1;
  if (dx <= 0 || dy <= 0) {
    throw ImageException(ImageException::Dimension, rx1, rx2, dx, ry1, ry2, dy, 
			 __FILE__":GeoImage::mask", __LINE__);
  }

  FILE *of = fopen(fname.toLatin1().constData(), "w");
  if (!of) {
    throw FileIOException(FileIOException::OPEN_FAILED, fname, 
			  __FILE__":GeoImage::mask", __LINE__);
    return "";
  }

  bit **dat_b_out = pbm_allocarray(dx, dy);
  switch (type_) {
  case PFM_FLOAT:
    GenMaskBlockStorage(float);
    break;
  case PFM_UINT:
    GenMaskBlockStorage(unsigned int);
    break;
  case PFM_SINT:
    GenMaskBlockStorage(signed int);
    break;
  case PFM_UINT16:
    GenMaskBlockStorage(unsigned short);
    break;
  case PFM_SINT16:
    GenMaskBlockStorage(signed short);
    break;
  case PBM:{
      bit *iptr;
      bit *optr;
      int x, y;
      for (y = 0; y < dy; y++) {
        iptr = (((bit **) data_p)[y + ry1]) + rx1;
        optr = dat_b_out[y];
        for (x = 0; x < dx; x++) {
          *optr = (*iptr == (bit) id ? 1 : 0);
          optr++;
          iptr++;
        }
      }
    }
//              GenMaskRowStorage(bit);
    break;
  case PFM_BYTE:
    GenMaskBlockStorage(unsigned char);
    break;
  default:
    pbm_freearray(dat_b_out, dy);
    fclose(of);
    return "";
    break;
  }
  pbm_writepbm(of, (bit **) dat_b_out, dx, dy, 0);
  pbm_freearray(dat_b_out, dy);

  fclose(of);
  return fname;
#undef GenMaskBlockStorage
#undef GenMaskRowStorage
}