/* ciitestbufferedseparationimage.c
** Michael Plass, July 1, 1993 12:09:45 pm PDT
** The original test case came from Shiva.
**
** MFP, July 1, 1993:
**   Used GC←malloc in place of malloc.
**   Added fillLines parameter to MakeTestBitMask, to make bars going in the
**   other direction.
**   Split BufferedSeparationImage call into two, to test sMin, sMax parameters.
**   Added RGB test case.
**   Added return-code checks.
*/
/* Michael Plass, September 28, 1993 2:16 pm PDT */
/* Willie-s, October 14, 1993 11:44 am PDT */

#include "cii.h"
#include "cii←matrix.h"

/* #include <memory.h> -- but sun's memory.h is not ANSI */
char *memset(char *s, int c, int n);

#define NIL ((void*)0)
#define NULL ((void*)0)
#define CRASH (*((int*)1))=0

#ifdef DEBUG
#define CHK(x) {res=x; if (CII←RES←ok!=res) CRASH;}
        /* debugging CHK intentionally crashes if there is an error */
#else
#define CHK(x) {res=x; if (CII←RES←ok!=res) return(res);}
#endif

static CII←RasterRep *
MakeTestBitMask(
  int sMin,
  int sMax,
  int fMin,
  int fMax,
  CII←Boolean fillLines
  )
{
  unsigned numBits;
  CII←RasterRep *ras;
  long *bitmap;
  int nbytes, maxCount;
  
  if ((ras = (CII←RasterRep *) GC←malloc(sizeof(CII←RasterRep))) == NULL)
    return NULL;
  ras->sMinBox = sMin;
  ras->fMinBox = fMin;
  ras->sMaxBox = sMax;
  ras->fMaxBox = fMax;
  ras->bitsPerSample = 1;
  /* make sure that bits Mask is integral multiple of 32 */
  numBits = ((fMax - fMin) / 32) * 32;
  if (numBits != (fMax - fMin))
    numBits += 32;
  ras->bitsPerLine = numBits;
  ras->basePointer = NULL;
  ras->bitIndex = 0;
  ras->ref = NULL;
  nbytes = (numBits / 8) * (sMax - sMin);
  if ((bitmap = (long *) GC←malloc←atomic(nbytes)) == NULL) {
    GC←free(ras);
    return NULL;
  }
  memset((char *) bitmap, 0, nbytes);
  maxCount = sMax - sMin;
  if (fillLines)
  {
    /* Turn every third scanline white */
    int count;
    unsigned char *line, *limit, *ptr;
    line = (unsigned char *) bitmap;
    for (count = 0; count < maxCount; count += 3) {
      for (ptr = line + count * numBits / 8,
  	   limit = ptr + numBits / 8;
	   ptr < limit;
	   ptr++) {
        if (((unsigned)ptr) >= ((unsigned)bitmap)+((unsigned)nbytes))
           CRASH; /* crash if we are past the end */
        *ptr = 0xFF;
      }
    }
  } else {
    /* Make bars perpendicular to the scan lines */
    memset((char*)bitmap, 0x0F, nbytes);
  }
  ras->basePointer = bitmap;
  ras->ref = bitmap;
  return ras;
}

extern CII←RES
run←ciitestbufferedseparationimage←gray(CII←Handle handle)
{
	CII←RES res = CII←RES←ok;
	CII←ColorOperator co = NULL; /* golbahar */
	CII←SampleRange sampleRange; /* golbahar */
	CII←RasterRep* buffers[1];
	
	sampleRange.sWhite = 1.0;
	sampleRange.sBlack = 0.0;
	CHK(CII←MakeGrayColorOperator(handle, &sampleRange, 0, NULL, &co));
	buffers[0] = MakeTestBitMask(60, 400, 60, 400, 1);
	CHK(CII←BufferedSeparationImage(
	  handle,
	  buffers,
	  1,          /* samples per pixel */
	  60,         /* sMin */
	  280,        /* sMax */
	  co,         /* colorOperator */
	  0/*false*/  /* interpolate */
	  ));
	CHK(CII←BufferedSeparationImage(
	  handle,
	  buffers,
	  1,          /* samples per pixel */
	  320,        /* sMin */
	  400,        /* sMax */
	  co,         /* colorOperator */
	  0/*false*/  /* interpolate */
	  ));
	CHK(CII←DestroyColorOperator(handle, co));
	return(res);
}

extern CII←RES
run←ciitestbufferedseparationimage←rgb(CII←Handle handle)
{
	CII←RES res = CII←RES←ok;
	CII←ColorOperator co = NULL; /* golbahar */
	CII←SampleRange sampleRange; /* golbahar */
	CII←RasterRep* buffers[1];
	
	sampleRange.sWhite = 1.0;
	sampleRange.sBlack = 0.0;
	CHK(CII←MakeRGBColorOperator(handle, &sampleRange, 0, NULL, NULL, NULL, &co));
	buffers[0] = MakeTestBitMask(400, 600, 60, 400, 1);
	buffers[1] = MakeTestBitMask(400, 600, 60, 400, 0);
	buffers[2] = MakeTestBitMask(400, 600, 60, 400, 0);
	CHK(CII←BufferedSeparationImage(
	  handle,
	  buffers,
	  3,          /* samples per pixel */
	  400,        /* sMin */
	  600,        /* sMax */
	  co,         /* colorOperator */
	  0/*false*/  /* interpolate */
	  ));
	CHK(CII←DestroyColorOperator(handle, co));
	return(res);
}

extern CII←RES
run←ciitestbufferedinterleavedimage←gray(CII←Handle handle)
{
	CII←RES res = CII←RES←ok;
	CII←ColorOperator co = NULL; /* golbahar */
	CII←SampleRange sampleRange; /* golbahar */
	CII←RasterRep * buffer;
	sampleRange.sWhite = 1.0;
	sampleRange.sBlack = 0.0;
	CHK(CII←MakeGrayColorOperator(handle, &sampleRange, 0, NULL, &co));
	buffer = MakeTestBitMask(60, 400, 0, 99, 0);
	CHK(CII←BufferedInterleavedImage(
	  handle,
	  buffer,
	  1,          /* samples per pixel */
	  60,         /* sMin */
	  400,        /* sMax */
	  co,         /* colorOperator */
	  0/*false*/  /* interpolate */
	  ));
	CHK(CII←DestroyColorOperator(handle, co));
	return(res);
}

extern CII←RES
run←ciitestbufferedinterleavedimage←rgb(CII←Handle handle)
{
	CII←RES res = CII←RES←ok;
	CII←ColorOperator co = NULL; /* golbahar */
	CII←SampleRange sampleRange; /* golbahar */
	CII←RasterRep * buffer;
	float save[6];
	float matrix[6];
	
	sampleRange.sWhite = 1.0;
	sampleRange.sBlack = 0.0;
	CHK(CII←MakeRGBColorOperator(handle, &sampleRange, 0, NULL, NULL, NULL, &co));
	buffer = MakeTestBitMask(60, 400, 0, 99, 0);
	CHK(CII←GetMatrix(handle, save));
	CHK(CII←GetMatrix(handle, matrix));
	CHK(CIU←ApplyPreScale(3, matrix));
	CHK(CII←SetMatrix(handle, matrix));
	CHK(CII←BufferedInterleavedImage(
	  handle,
	  buffer,
	  3,          /* samples per pixel */
	  60,         /* sMin */
	  400,        /* sMax */
	  co,         /* colorOperator */
	  0/*false*/  /* interpolate */
	  ));
	CHK(CII←DestroyColorOperator(handle, co));
	CHK(CII←SetMatrix(handle, save));
	return(res);
}

extern void
XR←run←ciitestbufferedseparationimage() {
	CII←Handle h = (CII←Handle)CII←TestDevice();
	float t[6];
	CII←GetInitialMatrix(h, t);
	CII←SetMatrix(h, t);
	run←ciitestbufferedseparationimage←gray(h);
	run←ciitestbufferedseparationimage←rgb(h);
	run←ciitestbufferedinterleavedimage←rgb(h);
	run←ciitestbufferedinterleavedimage←gray(h);
	CII←Destroy(h);
}