예제 #1
0
void
cupsImageSetMaxTiles(
    cups_image_t *img,			/* I - Image to set */
    int          max_tiles)		/* I - Number of tiles to cache */
{
  int	cache_size,			/* Size of tile cache in bytes */
	min_tiles,			/* Minimum number of tiles to cache */
	max_size;			/* Maximum cache size in bytes */
  char	*cache_env,			/* Cache size environment variable */
	cache_units[255];		/* Cache size units */


  min_tiles = max(CUPS_TILE_MINIMUM,
                  1 + max((img->xsize + CUPS_TILE_SIZE - 1) / CUPS_TILE_SIZE,
                          (img->ysize + CUPS_TILE_SIZE - 1) / CUPS_TILE_SIZE));

  if (max_tiles == 0)
    max_tiles = ((img->xsize + CUPS_TILE_SIZE - 1) / CUPS_TILE_SIZE) *
                ((img->ysize + CUPS_TILE_SIZE - 1) / CUPS_TILE_SIZE);

  cache_size = max_tiles * CUPS_TILE_SIZE * CUPS_TILE_SIZE *
               cupsImageGetDepth(img);

  if ((cache_env = getenv("RIP_MAX_CACHE")) != NULL)
  {
    switch (sscanf(cache_env, "%d%254s", &max_size, cache_units))
    {
      case 0 :
          max_size = 32 * 1024 * 1024;
	  break;
      case 1 :
          max_size *= 4 * CUPS_TILE_SIZE * CUPS_TILE_SIZE;
	  break;
      case 2 :
          if (tolower(cache_units[0] & 255) == 'g')
	    max_size *= 1024 * 1024 * 1024;
          else if (tolower(cache_units[0] & 255) == 'm')
	    max_size *= 1024 * 1024;
	  else if (tolower(cache_units[0] & 255) == 'k')
	    max_size *= 1024;
	  else if (tolower(cache_units[0] & 255) == 't')
	    max_size *= 4 * CUPS_TILE_SIZE * CUPS_TILE_SIZE;
	  break;
    }
  }
  else
    max_size = 32 * 1024 * 1024;

  if (cache_size > max_size)
    max_tiles = max_size / CUPS_TILE_SIZE / CUPS_TILE_SIZE /
                cupsImageGetDepth(img);

  if (max_tiles < min_tiles)
    max_tiles = min_tiles;

  img->max_ics = max_tiles;

  DEBUG_printf(("max_ics=%d...\n", img->max_ics));
}
예제 #2
0
static void
flush_tile(cups_image_t *img)		/* I - Image */
{
  int		bpp;			/* Bytes per pixel */
  cups_itile_t	*tile;			/* Pointer to tile */


  bpp  = cupsImageGetDepth(img);
  tile = img->first->tile;

  if (!tile->dirty)
  {
    tile->ic = NULL;
    return;
  }

  if (img->cachefile < 0)
  {
    if ((img->cachefile = cupsTempFd(img->cachename,
                                     sizeof(img->cachename))) < 0)
    {
      tile->ic    = NULL;
      tile->dirty = 0;
      return;
    }

    DEBUG_printf(("Created swap file \"%s\"...\n", img->cachename));
  }

  if (tile->pos >= 0)
  {
    if (lseek(img->cachefile, tile->pos, SEEK_SET) != tile->pos)
    {
      tile->ic    = NULL;
      tile->dirty = 0;
      return;
    }
  }
  else
  {
    if ((tile->pos = lseek(img->cachefile, 0, SEEK_END)) < 0)
    {
      tile->ic    = NULL;
      tile->dirty = 0;
      return;
    }
  }

  write(img->cachefile, tile->ic->pixels, bpp * CUPS_TILE_SIZE * CUPS_TILE_SIZE);

  tile->ic    = NULL;
  tile->dirty = 0;
}
예제 #3
0
int					/* O - Read status */
_cupsImageReadPNG(
    cups_image_t    *img,		/* IO - cupsImage */
    FILE            *fp,		/* I - cupsImage file */
    cups_icspace_t  primary,		/* I - Primary choice for colorspace */
    cups_icspace_t  secondary,		/* I - Secondary choice for colorspace */
    int             saturation,		/* I - Color saturation (%) */
    int             hue,		/* I - Color hue (degrees) */
    const cups_ib_t *lut)		/* I - Lookup table for gamma/brightness */
{
  int		y;			/* Looping var */
  png_structp	pp;			/* PNG read pointer */
  png_infop	info;			/* PNG info pointers */
  png_uint_32	width,			/* Width of image */
		height;			/* Height of image */
  int		bit_depth,		/* Bit depth */
		color_type,		/* Color type */
		interlace_type,		/* Interlace type */
		compression_type,	/* Compression type */
		filter_type;		/* Filter type */
  png_uint_32	xppm,			/* X pixels per meter */
		yppm;			/* Y pixels per meter */
  int		bpp;			/* Bytes per pixel */
  int		pass,			/* Current pass */
		passes;			/* Number of passes required */
  cups_ib_t	*in,			/* Input pixels */
		*inptr,			/* Pointer into pixels */
		*out;			/* Output pixels */
  png_color_16	bg;			/* Background color */


 /*
  * Setup the PNG data structures...
  */

  pp   = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
  info = png_create_info_struct(pp);

 /*
  * Initialize the PNG read "engine"...
  */

  png_init_io(pp, fp);

 /*
  * Get the image dimensions and load the output image...
  */

  png_read_info(pp, info);

  png_get_IHDR(pp, info, &width, &height, &bit_depth, &color_type,
               &interlace_type, &compression_type, &filter_type);

  fprintf(stderr, "DEBUG: PNG image: %dx%dx%d, color_type=%x (%s%s%s)\n",
          (int)width, (int)height, bit_depth, color_type,
	  (color_type & PNG_COLOR_MASK_COLOR) ? "RGB" : "GRAYSCALE",
	  (color_type & PNG_COLOR_MASK_ALPHA) ? "+ALPHA" : "",
	  (color_type & PNG_COLOR_MASK_PALETTE) ? "+PALETTE" : "");

  if (color_type & PNG_COLOR_MASK_PALETTE)
    png_set_expand(pp);
  else if (bit_depth < 8)
  {
    png_set_packing(pp);
    png_set_expand(pp);
  }
  else if (bit_depth == 16)
    png_set_strip_16(pp);

  if (color_type & PNG_COLOR_MASK_COLOR)
    img->colorspace = (primary == CUPS_IMAGE_RGB_CMYK) ? CUPS_IMAGE_RGB :
                                                         primary;
  else
    img->colorspace = secondary;

  if (width == 0 || width > CUPS_IMAGE_MAX_WIDTH ||
      height == 0 || height > CUPS_IMAGE_MAX_HEIGHT)
  {
    fprintf(stderr, "DEBUG: PNG image has invalid dimensions %ux%u!\n",
            (unsigned)width, (unsigned)height);
    fclose(fp);
    return (1);
  }

  img->xsize = width;
  img->ysize = height;

  if ((xppm = png_get_x_pixels_per_meter(pp, info)) != 0 &&
      (yppm = png_get_y_pixels_per_meter(pp, info)) != 0)
  {
    img->xppi = (int)((float)xppm * 0.0254);
    img->yppi = (int)((float)yppm * 0.0254);

    if (img->xppi == 0 || img->yppi == 0)
    {
      fprintf(stderr, "DEBUG: PNG image has invalid resolution %dx%d PPI\n",
              img->xppi, img->yppi);

      img->xppi = img->yppi = 128;
    }
  }

  cupsImageSetMaxTiles(img, 0);

  passes = png_set_interlace_handling(pp);

 /*
  * Handle transparency...
  */

  if (png_get_valid(pp, info, PNG_INFO_tRNS))
    png_set_tRNS_to_alpha(pp);

  bg.red   = 65535;
  bg.green = 65535;
  bg.blue  = 65535;

  png_set_background(pp, &bg, PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0);

  if (passes == 1)
  {
   /*
    * Load one row at a time...
    */

    if (color_type == PNG_COLOR_TYPE_GRAY ||
	color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
      in = malloc(img->xsize);
    else
      in = malloc(img->xsize * 3);
  }
  else
  {
   /*
    * Interlaced images must be loaded all at once...
    */

    size_t bufsize;			/* Size of buffer */


    if (color_type == PNG_COLOR_TYPE_GRAY ||
	color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
    {
      bufsize = img->xsize * img->ysize;

      if ((bufsize / img->ysize) != img->xsize)
      {
	fprintf(stderr, "DEBUG: PNG image dimensions (%ux%u) too large!\n",
		(unsigned)width, (unsigned)height);
	fclose(fp);
	return (1);
      }
    }
    else
    {
      bufsize = img->xsize * img->ysize * 3;

      if ((bufsize / (img->ysize * 3)) != img->xsize)
      {
	fprintf(stderr, "DEBUG: PNG image dimensions (%ux%u) too large!\n",
		(unsigned)width, (unsigned)height);
	fclose(fp);
	return (1);
      }
    }

    in = malloc(bufsize);
  }

  bpp = cupsImageGetDepth(img);
  out = malloc(img->xsize * bpp);

  if (!in || !out)
  {
    fputs("DEBUG: Unable to allocate memory for PNG image!\n", stderr);

    if (in)
      free(in);

    if (out)
      free(out);

    fclose(fp);

    return (1);
  }

 /*
  * Read the image, interlacing as needed...
  */

  for (pass = 1; pass <= passes; pass ++)
    for (inptr = in, y = 0; y < img->ysize; y ++)
    {
      png_read_row(pp, (png_bytep)inptr, NULL);

      if (pass == passes)
      {
       /*
        * Output this row...
	*/

	if (color_type & PNG_COLOR_MASK_COLOR)
	{
	  if ((saturation != 100 || hue != 0) && bpp > 1)
	    cupsImageRGBAdjust(inptr, img->xsize, saturation, hue);

	  switch (img->colorspace)
	  {
	    case CUPS_IMAGE_WHITE :
		cupsImageRGBToWhite(inptr, out, img->xsize);
		break;
	    case CUPS_IMAGE_RGB :
	    case CUPS_IMAGE_RGB_CMYK :
		cupsImageRGBToRGB(inptr, out, img->xsize);
		break;
	    case CUPS_IMAGE_BLACK :
		cupsImageRGBToBlack(inptr, out, img->xsize);
		break;
	    case CUPS_IMAGE_CMY :
		cupsImageRGBToCMY(inptr, out, img->xsize);
		break;
	    case CUPS_IMAGE_CMYK :
		cupsImageRGBToCMYK(inptr, out, img->xsize);
		break;
	  }
	}
	else
	{
	  switch (img->colorspace)
	  {
	    case CUPS_IMAGE_WHITE :
		memcpy(out, inptr, img->xsize);
		break;
	    case CUPS_IMAGE_RGB :
	    case CUPS_IMAGE_RGB_CMYK :
		cupsImageWhiteToRGB(inptr, out, img->xsize);
		break;
	    case CUPS_IMAGE_BLACK :
		cupsImageWhiteToBlack(inptr, out, img->xsize);
		break;
	    case CUPS_IMAGE_CMY :
		cupsImageWhiteToCMY(inptr, out, img->xsize);
		break;
	    case CUPS_IMAGE_CMYK :
		cupsImageWhiteToCMYK(inptr, out, img->xsize);
		break;
	  }
	}

	if (lut)
	  cupsImageLut(out, img->xsize * bpp, lut);

	_cupsImagePutRow(img, 0, y, img->xsize, out);
      }

      if (passes > 1)
      {
	if (color_type & PNG_COLOR_MASK_COLOR)
          inptr += img->xsize * 3;
	else
          inptr += img->xsize;
      }
    }

  png_read_end(pp, info);
  png_destroy_read_struct(&pp, &info, NULL);

  fclose(fp);
  free(in);
  free(out);

  return (0);
}
예제 #4
0
static cups_ib_t *			/* O - Pointer to tile or NULL */
get_tile(cups_image_t *img,		/* I - Image */
         int          x,		/* I - Column in image */
         int          y)		/* I - Row in image */
{
  int		bpp,			/* Bytes per pixel */
		tilex,			/* Column within tile */
		tiley,			/* Row within tile */
		xtiles,			/* Number of tiles horizontally */
		ytiles;			/* Number of tiles vertically */
  cups_ic_t	*ic;			/* Cache pointer */
  cups_itile_t	*tile;			/* Tile pointer */


  if (img->tiles == NULL)
  {
    xtiles = (img->xsize + CUPS_TILE_SIZE - 1) / CUPS_TILE_SIZE;
    ytiles = (img->ysize + CUPS_TILE_SIZE - 1) / CUPS_TILE_SIZE;

    DEBUG_printf(("Creating tile array (%dx%d)\n", xtiles, ytiles));

    if ((img->tiles = calloc(sizeof(cups_itile_t *), ytiles)) == NULL)
      return (NULL);

    if ((tile = calloc(xtiles * sizeof(cups_itile_t), ytiles)) == NULL)
      return (NULL);

    for (tiley = 0; tiley < ytiles; tiley ++)
    {
      img->tiles[tiley] = tile;
      for (tilex = xtiles; tilex > 0; tilex --, tile ++)
        tile->pos = -1;
    }
  }

  bpp   = cupsImageGetDepth(img);
  tilex = x / CUPS_TILE_SIZE;
  tiley = y / CUPS_TILE_SIZE;
  tile  = img->tiles[tiley] + tilex;
  x     &= (CUPS_TILE_SIZE - 1);
  y     &= (CUPS_TILE_SIZE - 1);

  if ((ic = tile->ic) == NULL)
  {
    if (img->num_ics < img->max_ics)
    {
      if ((ic = calloc(sizeof(cups_ic_t) +
                       bpp * CUPS_TILE_SIZE * CUPS_TILE_SIZE, 1)) == NULL)
      {
        if (img->num_ics == 0)
	  return (NULL);

        flush_tile(img);
	ic = img->first;
      }
      else
      {
	ic->pixels = ((cups_ib_t *)ic) + sizeof(cups_ic_t);

	img->num_ics ++;

	DEBUG_printf(("Allocated cache tile %d (%p)...\n", img->num_ics, ic));
      }
    }
    else
    {
      DEBUG_printf(("Flushing old cache tile (%p)...\n", img->first));

      flush_tile(img);
      ic = img->first;
    }

    ic->tile = tile;
    tile->ic = ic;

    if (tile->pos >= 0)
    {
      DEBUG_printf(("Loading cache tile from file position " CUPS_LLFMT "...\n",
                    CUPS_LLCAST tile->pos));

      lseek(img->cachefile, tile->pos, SEEK_SET);
      read(img->cachefile, ic->pixels, bpp * CUPS_TILE_SIZE * CUPS_TILE_SIZE);
    }
    else
    {
      DEBUG_puts("Clearing cache tile...");

      memset(ic->pixels, 0, bpp * CUPS_TILE_SIZE * CUPS_TILE_SIZE);
    }
  }

  if (ic == img->first)
  {
    if (ic->next != NULL)
      ic->next->prev = NULL;

    img->first = ic->next;
    ic->next   = NULL;
    ic->prev   = NULL;
  }
  else if (img->first == NULL)
    img->first = ic;

  if (ic != img->last)
  {
   /*
    * Remove the cache entry from the list...
    */

    if (ic->prev != NULL)
      ic->prev->next = ic->next;
    if (ic->next != NULL)
      ic->next->prev = ic->prev;

   /*
    * And add it to the end...
    */

    if (img->last != NULL)
      img->last->next = ic;

    ic->prev  = img->last;
    img->last = ic;
  }

  ic->next = NULL;

  return (ic->pixels + bpp * (y * CUPS_TILE_SIZE + x));
}
예제 #5
0
int					/* O - -1 on error, 0 on success */
_cupsImagePutCol(
    cups_image_t    *img,		/* I - Image */
    int             x,			/* I - Column */
    int             y,			/* I - Start row */
    int             height,		/* I - Column height */
    const cups_ib_t *pixels)		/* I - Pixels to put */
{
  int		bpp,			/* Bytes per pixel */
		twidth,			/* Width of tile */
		count;			/* Number of pixels to put */
  int		tilex,			/* Column within tile */
		tiley;			/* Row within tile */
  cups_ib_t	*ib;			/* Pointer to pixels in tile */


  if (img == NULL || x < 0 || x >= img->xsize || y >= img->ysize)
    return (-1);

  if (y < 0)
  {
    height += y;
    y = 0;
  }

  if ((y + height) > img->ysize)
    height = img->ysize - y;

  if (height < 1)
    return (-1);

  bpp    = cupsImageGetDepth(img);
  twidth = bpp * (CUPS_TILE_SIZE - 1);
  tilex  = x / CUPS_TILE_SIZE;
  tiley  = y / CUPS_TILE_SIZE;

  while (height > 0)
  {
    ib = get_tile(img, x, y);

    if (ib == NULL)
      return (-1);

    img->tiles[tiley][tilex].dirty = 1;
    tiley ++;

    count = CUPS_TILE_SIZE - (y & (CUPS_TILE_SIZE - 1));
    if (count > height)
      count = height;

    y      += count;
    height -= count;

    for (; count > 0; count --, ib += twidth)
      switch (bpp)
      {
        case 4 :
            *ib++ = *pixels++;
        case 3 :
            *ib++ = *pixels++;
            *ib++ = *pixels++;
        case 1 :
            *ib++ = *pixels++;
            break;
      }
  }

  return (0);
}
예제 #6
0
int					/* O - Read status */
_cupsImageReadSGI(
    cups_image_t    *img,		/* IO - cupsImage */
    FILE            *fp,		/* I - cupsImage file */
    cups_icspace_t  primary,		/* I - Primary choice for colorspace */
    cups_icspace_t  secondary,		/* I - Secondary choice for colorspace */
    int             saturation,		/* I - Color saturation (%) */
    int             hue,		/* I - Color hue (degrees) */
    const cups_ib_t *lut)		/* I - Lookup table for gamma/brightness */
{
  int		i, y;			/* Looping vars */
  int		bpp;			/* Bytes per pixel */
  sgi_t		*sgip;			/* SGI image file */
  cups_ib_t	*in,			/* Input pixels */
		*inptr,			/* Current input pixel */
		*out;			/* Output pixels */
  unsigned short *rows[4],		/* Row pointers for image data */
		*red,
		*green,
		*blue,
		*gray,
		*alpha;


 /*
  * Setup the SGI file...
  */

  sgip = sgiOpenFile(fp, SGI_READ, 0, 0, 0, 0, 0);

 /*
  * Get the image dimensions and load the output image...
  */

 /*
  * Check the image dimensions; since xsize and ysize are unsigned shorts,
  * just check if they are 0 since they can't exceed CUPS_IMAGE_MAX_WIDTH or
  * CUPS_IMAGE_MAX_HEIGHT...
  */

  if (sgip->xsize == 0 || sgip->ysize == 0 ||
      sgip->zsize == 0 || sgip->zsize > 4)
  {
    fprintf(stderr, "DEBUG: Bad SGI image dimensions %ux%ux%u!\n",
            sgip->xsize, sgip->ysize, sgip->zsize);
    sgiClose(sgip);
    return (1);
  }

  if (sgip->zsize < 3)
    img->colorspace = secondary;
  else
    img->colorspace = (primary == CUPS_IMAGE_RGB_CMYK) ? CUPS_IMAGE_RGB : primary;

  img->xsize = sgip->xsize;
  img->ysize = sgip->ysize;

  cupsImageSetMaxTiles(img, 0);

  bpp = cupsImageGetDepth(img);

  if ((in = malloc(img->xsize * sgip->zsize)) == NULL)
  {
    fputs("DEBUG: Unable to allocate memory!\n", stderr);
    sgiClose(sgip);
    return (1);
  }

  if ((out = malloc(img->xsize * bpp)) == NULL)
  {
    fputs("DEBUG: Unable to allocate memory!\n", stderr);
    sgiClose(sgip);
    free(in);
    return (1);
  }

  if ((rows[0] = calloc(img->xsize * sgip->zsize,
                        sizeof(unsigned short))) == NULL)
  {
    fputs("DEBUG: Unable to allocate memory!\n", stderr);
    sgiClose(sgip);
    free(in);
    free(out);
    return (1);
  }

  for (i = 1; i < sgip->zsize; i ++)
    rows[i] = rows[0] + i * img->xsize;

 /*
  * Read the SGI image file...
  */

  for (y = 0; y < img->ysize; y ++)
  {
    for (i = 0; i < sgip->zsize; i ++)
      sgiGetRow(sgip, rows[i], img->ysize - 1 - y, i);

    switch (sgip->zsize)
    {
      case 1 :
          if (sgip->bpp == 1)
	    for (i = img->xsize - 1, gray = rows[0], inptr = in;
		 i >= 0;
		 i --)
            {
              *inptr++ = *gray++;
            }
          else
	    for (i = img->xsize - 1, gray = rows[0], inptr = in;
		 i >= 0;
		 i --)
            {
              *inptr++ = (*gray++) / 256 + 128;
            }
          break;
      case 2 :
          if (sgip->bpp == 1)
	    for (i = img->xsize - 1, gray = rows[0], alpha = rows[1], inptr = in;
		 i >= 0;
		 i --)
            {
              *inptr++ = (*gray++) * (*alpha++) / 255;
            }
          else
	    for (i = img->xsize - 1, gray = rows[0], alpha = rows[1], inptr = in;
		 i >= 0;
		 i --)
            {
              *inptr++ = ((*gray++) / 256 + 128) * (*alpha++) / 32767;
            }
          break;
      case 3 :
          if (sgip->bpp == 1)
	    for (i = img->xsize - 1, red = rows[0], green = rows[1],
	             blue = rows[2], inptr = in;
		 i >= 0;
		 i --)
            {
              *inptr++ = *red++;
              *inptr++ = *green++;
              *inptr++ = *blue++;
            }
          else
	    for (i = img->xsize - 1, red = rows[0], green = rows[1],
	             blue = rows[2], inptr = in;
		 i >= 0;
		 i --)
            {
              *inptr++ = (*red++) / 256 + 128;
              *inptr++ = (*green++) / 256 + 128;
              *inptr++ = (*blue++) / 256 + 128;
            }
          break;
      case 4 :
          if (sgip->bpp == 1)
	    for (i = img->xsize - 1, red = rows[0], green = rows[1],
	             blue = rows[2], alpha = rows[3], inptr = in;
		 i >= 0;
		 i --)
            {
              *inptr++ = (*red++) * (*alpha) / 255;
              *inptr++ = (*green++) * (*alpha) / 255;
              *inptr++ = (*blue++) * (*alpha++) / 255;
            }
          else
	    for (i = img->xsize - 1, red = rows[0], green = rows[1],
	             blue = rows[2], alpha = rows[3], inptr = in;
		 i >= 0;
		 i --)
            {
              *inptr++ = ((*red++) / 256 + 128) * (*alpha) / 32767;
              *inptr++ = ((*green++) / 256 + 128) * (*alpha) / 32767;
              *inptr++ = ((*blue++) / 256 + 128) * (*alpha++) / 32767;
            }
          break;
    }

    if (sgip->zsize < 3)
    {
      if (img->colorspace == CUPS_IMAGE_WHITE)
      {
        if (lut)
	  cupsImageLut(in, img->xsize, lut);

        _cupsImagePutRow(img, 0, y, img->xsize, in);
      }
      else
      {
	switch (img->colorspace)
	{
	  default :
	      break;

	  case CUPS_IMAGE_RGB :
	  case CUPS_IMAGE_RGB_CMYK :
	      cupsImageWhiteToRGB(in, out, img->xsize);
	      break;
	  case CUPS_IMAGE_BLACK :
	      cupsImageWhiteToBlack(in, out, img->xsize);
	      break;
	  case CUPS_IMAGE_CMY :
	      cupsImageWhiteToCMY(in, out, img->xsize);
	      break;
	  case CUPS_IMAGE_CMYK :
	      cupsImageWhiteToCMYK(in, out, img->xsize);
	      break;
	}

        if (lut)
	  cupsImageLut(out, img->xsize * bpp, lut);

        _cupsImagePutRow(img, 0, y, img->xsize, out);
      }
    }
    else
    {
      if ((saturation != 100 || hue != 0) && bpp > 1)
	cupsImageRGBAdjust(in, img->xsize, saturation, hue);

      switch (img->colorspace)
      {
	default :
	    break;

	case CUPS_IMAGE_WHITE :
	    cupsImageRGBToWhite(in, out, img->xsize);
	    break;
	case CUPS_IMAGE_RGB :
	    cupsImageRGBToRGB(in, out, img->xsize);
	    break;
	case CUPS_IMAGE_BLACK :
	    cupsImageRGBToBlack(in, out, img->xsize);
	    break;
	case CUPS_IMAGE_CMY :
	    cupsImageRGBToCMY(in, out, img->xsize);
	    break;
	case CUPS_IMAGE_CMYK :
	    cupsImageRGBToCMYK(in, out, img->xsize);
	    break;
      }

      if (lut)
	cupsImageLut(out, img->xsize * bpp, lut);

      _cupsImagePutRow(img, 0, y, img->xsize, out);
    }
  }

  free(in);
  free(out);
  free(rows[0]);

  sgiClose(sgip);

  return (0);
}
예제 #7
0
int					/* O - -1 on error, 0 on success */
cupsImageGetCol(cups_image_t *img,	/* I - Image */
        	int          x,		/* I - Column */
        	int          y,		/* I - Start row */
        	int          height,	/* I - Column height */
        	cups_ib_t    *pixels)	/* O - Pixel data */
{
  int			bpp,		/* Bytes per pixel */
			twidth,		/* Tile width */
			count;		/* Number of pixels to get */
  const cups_ib_t	*ib;		/* Pointer into tile */


  if (img == NULL || x < 0 || x >= img->xsize || y >= img->ysize)
    return (-1);

  if (y < 0)
  {
    height += y;
    y = 0;
  }

  if ((y + height) > img->ysize)
    height = img->ysize - y;

  if (height < 1)
    return (-1);

  bpp    = cupsImageGetDepth(img);
  twidth = bpp * (CUPS_TILE_SIZE - 1);

  while (height > 0)
  {
    ib = get_tile(img, x, y);

    if (ib == NULL)
      return (-1);

    count = CUPS_TILE_SIZE - (y & (CUPS_TILE_SIZE - 1));
    if (count > height)
      count = height;

    y      += count;
    height -= count;

    for (; count > 0; count --, ib += twidth)
      switch (bpp)
      {
        case 4 :
            *pixels++ = *ib++;
        case 3 :
            *pixels++ = *ib++;
            *pixels++ = *ib++;
        case 1 :
            *pixels++ = *ib++;
            break;
      }
  }

  return (0);
}
예제 #8
0
int					/* O - Read status */
_cupsImageReadGIF(
    cups_image_t    *img,		/* IO - cupsImage */
    FILE            *fp,		/* I - cupsImage file */
    cups_icspace_t  primary,		/* I - Primary choice for colorspace */
    cups_icspace_t  secondary,		/* I - Secondary choice for colorspace */
    int             saturation,		/* I - Color saturation (%) */
    int             hue,		/* I - Color hue (degrees) */
    const cups_ib_t *lut)		/* I - Lookup table for gamma/brightness */
{
  unsigned char	buf[1024];		/* Input buffer */
  gif_cmap_t	cmap;			/* Colormap */
  int		i,			/* Looping var */
		bpp,			/* Bytes per pixel */
		gray,			/* Grayscale image? */
		ncolors,		/* Bits per pixel */
		transparent;		/* Transparent color index */


 /*
  * GIF files are either grayscale or RGB - no CMYK...
  */

  if (primary == CUPS_IMAGE_RGB_CMYK)
    primary = CUPS_IMAGE_RGB;

 /*
  * Read the header; we already know it is a GIF file...
  */

  fread(buf, 13, 1, fp);

  img->xsize = (buf[7] << 8) | buf[6];
  img->ysize = (buf[9] << 8) | buf[8];
  ncolors    = 2 << (buf[10] & 0x07);
  gray       = primary == CUPS_IMAGE_BLACK || primary == CUPS_IMAGE_WHITE;

  if (buf[10] & GIF_COLORMAP)
    if (gif_read_cmap(fp, ncolors, cmap, &gray))
    {
      fclose(fp);
      return (-1);
    }

  transparent = -1;

  for (;;)
  {
    switch (getc(fp))
    {
      case ';' :	/* End of image */
          fclose(fp);
          return (-1);		/* Early end of file */

      case '!' :	/* Extension record */
          buf[0] = getc(fp);
          if (buf[0] == 0xf9)	/* Graphic Control Extension */
          {
            gif_get_block(fp, buf);
            if (buf[0] & 1)	/* Get transparent color index */
              transparent = buf[3];
          }

          while (gif_get_block(fp, buf) != 0);
          break;

      case ',' :	/* cupsImage data */
          fread(buf, 9, 1, fp);

          if (buf[8] & GIF_COLORMAP)
          {
            ncolors = 2 << (buf[8] & 0x07);
            gray = primary == CUPS_IMAGE_BLACK || primary == CUPS_IMAGE_WHITE;

	    if (gif_read_cmap(fp, ncolors, cmap, &gray))
	    {
              fclose(fp);
	      return (-1);
	    }
	  }

          if (transparent >= 0)
          {
           /*
            * Make transparent color white...
            */

            cmap[transparent][0] = 255;
            cmap[transparent][1] = 255;
            cmap[transparent][2] = 255;
          }

	  if (gray)
	  {
	    switch (secondary)
	    {
              case CUPS_IMAGE_CMYK :
        	  for (i = ncolors - 1; i >= 0; i --)
        	    cupsImageWhiteToCMYK(cmap[i], cmap[i], 1);
        	  break;
              case CUPS_IMAGE_CMY :
        	  for (i = ncolors - 1; i >= 0; i --)
        	    cupsImageWhiteToCMY(cmap[i], cmap[i], 1);
        	  break;
              case CUPS_IMAGE_BLACK :
        	  for (i = ncolors - 1; i >= 0; i --)
        	    cupsImageWhiteToBlack(cmap[i], cmap[i], 1);
        	  break;
              case CUPS_IMAGE_WHITE :
        	  break;
              case CUPS_IMAGE_RGB :
              case CUPS_IMAGE_RGB_CMYK :
        	  for (i = ncolors - 1; i >= 0; i --)
        	    cupsImageWhiteToRGB(cmap[i], cmap[i], 1);
        	  break;
	    }

            img->colorspace = secondary;
	  }
	  else
	  {
	    if (hue != 0 || saturation != 100)
              for (i = ncolors - 1; i >= 0; i --)
        	cupsImageRGBAdjust(cmap[i], 1, saturation, hue);

	    switch (primary)
	    {
              case CUPS_IMAGE_CMYK :
        	  for (i = ncolors - 1; i >= 0; i --)
        	    cupsImageRGBToCMYK(cmap[i], cmap[i], 1);
        	  break;
              case CUPS_IMAGE_CMY :
        	  for (i = ncolors - 1; i >= 0; i --)
        	    cupsImageRGBToCMY(cmap[i], cmap[i], 1);
        	  break;
              case CUPS_IMAGE_BLACK :
        	  for (i = ncolors - 1; i >= 0; i --)
        	    cupsImageRGBToBlack(cmap[i], cmap[i], 1);
        	  break;
              case CUPS_IMAGE_WHITE :
        	  for (i = ncolors - 1; i >= 0; i --)
        	    cupsImageRGBToWhite(cmap[i], cmap[i], 1);
        	  break;
              case CUPS_IMAGE_RGB :
              case CUPS_IMAGE_RGB_CMYK :
        	  for (i = ncolors - 1; i >= 0; i --)
        	    cupsImageRGBToRGB(cmap[i], cmap[i], 1);
        	  break;
	    }

            img->colorspace = primary;
	  }

          if (lut)
	  {
	    bpp = cupsImageGetDepth(img);

            for (i = ncolors - 1; i >= 0; i --)
              cupsImageLut(cmap[i], bpp, lut);
	  }

          img->xsize = (buf[5] << 8) | buf[4];
          img->ysize = (buf[7] << 8) | buf[6];

         /*
	  * Check the dimensions of the image; since the dimensions are
	  * a 16-bit integer we just need to check for 0...
	  */

          if (img->xsize == 0 || img->ysize == 0)
	  {
	    fprintf(stderr, "DEBUG: Bad GIF image dimensions: %dx%d\n",
	            img->xsize, img->ysize);
	    fclose(fp);
	    return (1);
	  }

	  i = gif_read_image(fp, img, cmap, buf[8] & GIF_INTERLACE);
          fclose(fp);
          return (i);
    }
  }
}
예제 #9
0
int					/* O - Read status */
_cupsImageReadPIX(
    cups_image_t    *img,		/* IO - cupsImage */
    FILE            *fp,		/* I - cupsImage file */
    cups_icspace_t  primary,		/* I - Primary choice for colorspace */
    cups_icspace_t  secondary,		/* I - Secondary choice for colorspace */
    int             saturation,		/* I - Color saturation (%) */
    int             hue,		/* I - Color hue (degrees) */
    const cups_ib_t *lut)		/* I - Lookup table for gamma/brightness */
{
  short		width,			/* Width of image */
		height,			/* Height of image */
		depth;			/* Depth of image (bits) */
  int		count,			/* Repetition count */
		bpp,			/* Bytes per pixel */
		x, y;			/* Looping vars */
  cups_ib_t	r, g, b;		/* Red, green/gray, blue values */
  cups_ib_t	*in,			/* Input pixels */
		*out,			/* Output pixels */
		*ptr;			/* Pointer into pixels */


 /*
  * Get the image dimensions and setup the image...
  */

  width  = read_short(fp);
  height = read_short(fp);
  read_short(fp);
  read_short(fp);
  depth  = read_short(fp);

 /*
  * Check the dimensions of the image.  Since the short values used for the
  * width and height cannot exceed CUPS_IMAGE_MAX_WIDTH or
  * CUPS_IMAGE_MAX_HEIGHT, we just need to verify they are positive integers.
  */

  if (width <= 0 || height <= 0 ||
      (depth != 8 && depth != 24))
  {
    fprintf(stderr, "DEBUG: Bad PIX image dimensions %dx%dx%d\n",
            width, height, depth);
    fclose(fp);
    return (1);
  }

  if (depth == 8)
    img->colorspace = secondary;
  else
    img->colorspace = (primary == CUPS_IMAGE_RGB_CMYK) ? CUPS_IMAGE_RGB : primary;

  img->xsize = width;
  img->ysize = height;

  cupsImageSetMaxTiles(img, 0);

  bpp = cupsImageGetDepth(img);

  if ((in = malloc(img->xsize * (depth / 8))) == NULL)
  {
    fputs("DEBUG: Unable to allocate memory!\n", stderr);
    fclose(fp);
    return (1);
  }

  if ((out = malloc(img->xsize * bpp)) == NULL)
  {
    fputs("DEBUG: Unable to allocate memory!\n", stderr);
    fclose(fp);
    free(in);
    return (1);
  }

 /*
  * Read the image data...
  */

  if (depth == 8)
  {
    for (count = 0, y = 0, g = 0; y < img->ysize; y ++)
    {
      if (img->colorspace == CUPS_IMAGE_WHITE)
        ptr = out;
      else
        ptr = in;

      for (x = img->xsize; x > 0; x --, count --)
      {
        if (count == 0)
	{
          count = getc(fp);
	  g     = getc(fp);
	}

        *ptr++ = g;
      }

      if (img->colorspace != CUPS_IMAGE_WHITE)
	switch (img->colorspace)
	{
	  default :
	      cupsImageWhiteToRGB(in, out, img->xsize);
	      break;
	  case CUPS_IMAGE_BLACK :
	      cupsImageWhiteToBlack(in, out, img->xsize);
	      break;
	  case CUPS_IMAGE_CMY :
	      cupsImageWhiteToCMY(in, out, img->xsize);
	      break;
	  case CUPS_IMAGE_CMYK :
	      cupsImageWhiteToCMYK(in, out, img->xsize);
	      break;
	}

      if (lut)
	cupsImageLut(out, img->xsize * bpp, lut);

      _cupsImagePutRow(img, 0, y, img->xsize, out);
    }
  }
  else
  {
    for (count = 0, y = 0, r = 0, g = 0, b = 0; y < img->ysize; y ++)
    {
      ptr = in;

      for (x = img->xsize; x > 0; x --, count --)
      {
        if (count == 0)
	{
          count = getc(fp);
	  b     = getc(fp);
	  g     = getc(fp);
	  r     = getc(fp);
	}

        *ptr++ = r;
        *ptr++ = g;
        *ptr++ = b;
      }

      if (saturation != 100 || hue != 0)
	cupsImageRGBAdjust(in, img->xsize, saturation, hue);

      switch (img->colorspace)
      {
	default :
	    break;

	case CUPS_IMAGE_WHITE :
	    cupsImageRGBToWhite(in, out, img->xsize);
	    break;
	case CUPS_IMAGE_RGB :
	    cupsImageRGBToWhite(in, out, img->xsize);
	    break;
	case CUPS_IMAGE_BLACK :
	    cupsImageRGBToBlack(in, out, img->xsize);
	    break;
	case CUPS_IMAGE_CMY :
	    cupsImageRGBToCMY(in, out, img->xsize);
	    break;
	case CUPS_IMAGE_CMYK :
	    cupsImageRGBToCMYK(in, out, img->xsize);
	    break;
      }

      if (lut)
	cupsImageLut(out, img->xsize * bpp, lut);

      _cupsImagePutRow(img, 0, y, img->xsize, out);
    }
  }

  fclose(fp);
  free(in);
  free(out);

  return (0);
}
예제 #10
0
static int				/* I - 0 = success, -1 = failure */
gif_read_image(FILE         *fp,	/* I - Input file */
	       cups_image_t *img,	/* I - cupsImage pointer */
	       gif_cmap_t   cmap,	/* I - Colormap */
	       int          interlace)	/* I - Non-zero = interlaced image */
{
  unsigned char		code_size;	/* Code size */
  cups_ib_t		*pixels,	/* Pixel buffer */
			*temp;		/* Current pixel */
  int			xpos,		/* Current X position */
			ypos,		/* Current Y position */
			pass;		/* Current pass */
  int			pixel;		/* Current pixel */
  int			bpp;		/* Bytes per pixel */
  static const int	xpasses[4] =	/* X interleaving */
			{ 8, 8, 4, 2 },
			ypasses[5] =	/* Y interleaving */
			{ 0, 4, 2, 1, 999999 };


  bpp       = cupsImageGetDepth(img);
  pixels    = calloc(bpp, img->xsize);
  xpos      = 0;
  ypos      = 0;
  pass      = 0;
  code_size = getc(fp);

  if (!pixels)
    return (-1);

  if (code_size > GIF_MAX_BITS || gif_read_lzw(fp, 1, code_size) < 0)
  {
    free(pixels);
    return (-1);
  }

  temp = pixels;
  while ((pixel = gif_read_lzw(fp, 0, code_size)) >= 0)
  {
    switch (bpp)
    {
      case 4 :
          temp[3] = cmap[pixel][3];
      case 3 :
          temp[2] = cmap[pixel][2];
      case 2 :
          temp[1] = cmap[pixel][1];
      default :
          temp[0] = cmap[pixel][0];
    }

    xpos ++;
    temp += bpp;
    if (xpos == img->xsize)
    {
      _cupsImagePutRow(img, 0, ypos, img->xsize, pixels);

      xpos = 0;
      temp = pixels;

      if (interlace)
      {
        ypos += xpasses[pass];

        if (ypos >= img->ysize)
	{
	  pass ++;

          ypos = ypasses[pass];
	}
      }
      else
	ypos ++;
    }

    if (ypos >= img->ysize)
      break;
  }

  free(pixels);

  return (0);
}
예제 #11
0
int					/* O  - Read status */
_cupsImageReadJPEG(
    cups_image_t    *img,		/* IO - cupsImage */
    FILE            *fp,		/* I  - cupsImage file */
    cups_icspace_t  primary,		/* I  - Primary choice for colorspace */
    cups_icspace_t  secondary,		/* I  - Secondary choice for colorspace */
    int             saturation,		/* I  - Color saturation (%) */
    int             hue,		/* I  - Color hue (degrees) */
    const cups_ib_t *lut)		/* I  - Lookup table for gamma/brightness */
{
  struct jpeg_decompress_struct	cinfo;	/* Decompressor info */
  struct jpeg_error_mgr	jerr;		/* Error handler info */
  cups_ib_t		*in,		/* Input pixels */
			*out;		/* Output pixels */
  jpeg_saved_marker_ptr	marker;		/* Pointer to marker data */
  int			psjpeg = 0;	/* Non-zero if Photoshop CMYK JPEG */
  static const char	*cspaces[] =
			{		/* JPEG colorspaces... */
			  "JCS_UNKNOWN",
			  "JCS_GRAYSCALE",
			  "JCS_RGB",
			  "JCS_YCbCr",
			  "JCS_CMYK",
			  "JCS_YCCK"
			};


 /*
  * Read the JPEG header...
  */

  cinfo.err = jpeg_std_error(&jerr);
  jpeg_create_decompress(&cinfo);
  jpeg_save_markers(&cinfo, JPEG_APP0 + 14, 0xffff); /* Adobe JPEG */
  jpeg_stdio_src(&cinfo, fp);
  jpeg_read_header(&cinfo, 1);

 /*
  * Parse any Adobe APPE data embedded in the JPEG file.  Since Adobe doesn't
  * bother following standards, we have to invert the CMYK JPEG data written by
  * Adobe apps...
  */

  for (marker = cinfo.marker_list; marker; marker = marker->next)
    if (marker->marker == (JPEG_APP0 + 14) && marker->data_length >= 12 &&
        !memcmp(marker->data, "Adobe", 5))
    {
      fputs("DEBUG: Adobe CMYK JPEG detected (inverting color values)\n",
	    stderr);
      psjpeg = 1;
    }

  cinfo.quantize_colors = 0;

  fprintf(stderr, "DEBUG: num_components = %d\n", cinfo.num_components);
  fprintf(stderr, "DEBUG: jpeg_color_space = %s\n",
          cspaces[cinfo.jpeg_color_space]);

  if (cinfo.num_components == 1)
  {
    fputs("DEBUG: Converting image to grayscale...\n", stderr);

    cinfo.out_color_space      = JCS_GRAYSCALE;
    cinfo.out_color_components = 1;
    cinfo.output_components    = 1;

    img->colorspace = secondary;
  }
  else if (cinfo.num_components == 4)
  {
    fputs("DEBUG: Converting image to CMYK...\n", stderr);

    cinfo.out_color_space      = JCS_CMYK;
    cinfo.out_color_components = 4;
    cinfo.output_components    = 4;

    img->colorspace = (primary == CUPS_IMAGE_RGB_CMYK) ? CUPS_IMAGE_CMYK : primary;
  }
  else
  {
    fputs("DEBUG: Converting image to RGB...\n", stderr);

    cinfo.out_color_space      = JCS_RGB;
    cinfo.out_color_components = 3;
    cinfo.output_components    = 3;

    img->colorspace = (primary == CUPS_IMAGE_RGB_CMYK) ? CUPS_IMAGE_RGB : primary;
  }

  jpeg_calc_output_dimensions(&cinfo);

  if (cinfo.output_width <= 0 || cinfo.output_width > CUPS_IMAGE_MAX_WIDTH ||
      cinfo.output_height <= 0 || cinfo.output_height > CUPS_IMAGE_MAX_HEIGHT)
  {
    fprintf(stderr, "DEBUG: Bad JPEG dimensions %dx%d!\n",
            cinfo.output_width, cinfo.output_height);

    jpeg_destroy_decompress(&cinfo);

    fclose(fp);
    return (1);
  }

  img->xsize      = cinfo.output_width;
  img->ysize      = cinfo.output_height;

  if (cinfo.X_density > 0 && cinfo.Y_density > 0 && cinfo.density_unit > 0)
  {
    if (cinfo.density_unit == 1)
    {
      img->xppi = cinfo.X_density;
      img->yppi = cinfo.Y_density;
    }
    else
    {
      img->xppi = (int)((float)cinfo.X_density * 2.54);
      img->yppi = (int)((float)cinfo.Y_density * 2.54);
    }

    if (img->xppi == 0 || img->yppi == 0)
    {
      fprintf(stderr, "DEBUG: Bad JPEG image resolution %dx%d PPI.\n",
              img->xppi, img->yppi);
      img->xppi = img->yppi = 128;
    }
  }

  fprintf(stderr, "DEBUG: JPEG image %dx%dx%d, %dx%d PPI\n",
          img->xsize, img->ysize, cinfo.output_components,
	  img->xppi, img->yppi);

  cupsImageSetMaxTiles(img, 0);

  in  = malloc(img->xsize * cinfo.output_components);
  out = malloc(img->xsize * cupsImageGetDepth(img));

  jpeg_start_decompress(&cinfo);

  while (cinfo.output_scanline < cinfo.output_height)
  {
    jpeg_read_scanlines(&cinfo, (JSAMPROW *)&in, (JDIMENSION)1);

    if (psjpeg && cinfo.output_components == 4)
    {
     /*
      * Invert CMYK data from Photoshop...
      */

      cups_ib_t	*ptr;	/* Pointer into buffer */
      int	i;	/* Looping var */


      for (ptr = in, i = img->xsize * 4; i > 0; i --, ptr ++)
        *ptr = 255 - *ptr;
    }

    if ((saturation != 100 || hue != 0) && cinfo.output_components == 3)
      cupsImageRGBAdjust(in, img->xsize, saturation, hue);

    if ((img->colorspace == CUPS_IMAGE_WHITE && cinfo.out_color_space == JCS_GRAYSCALE) ||
	(img->colorspace == CUPS_IMAGE_CMYK && cinfo.out_color_space == JCS_CMYK))
    {
#ifdef DEBUG
      int	i, j;
      cups_ib_t	*ptr;


      fputs("DEBUG: Direct Data...\n", stderr);

      fputs("DEBUG:", stderr);

      for (i = 0, ptr = in; i < img->xsize; i ++)
      {
        putc(' ', stderr);
	for (j = 0; j < cinfo.output_components; j ++, ptr ++)
	  fprintf(stderr, "%02X", *ptr & 255);
      }

      putc('\n', stderr);
#endif /* DEBUG */

      if (lut)
        cupsImageLut(in, img->xsize * cupsImageGetDepth(img), lut);

      _cupsImagePutRow(img, 0, cinfo.output_scanline - 1, img->xsize, in);
    }
    else if (cinfo.out_color_space == JCS_GRAYSCALE)
    {
      switch (img->colorspace)
      {
        default :
	    break;

        case CUPS_IMAGE_BLACK :
            cupsImageWhiteToBlack(in, out, img->xsize);
            break;
        case CUPS_IMAGE_RGB :
            cupsImageWhiteToRGB(in, out, img->xsize);
            break;
        case CUPS_IMAGE_CMY :
            cupsImageWhiteToCMY(in, out, img->xsize);
            break;
        case CUPS_IMAGE_CMYK :
            cupsImageWhiteToCMYK(in, out, img->xsize);
            break;
      }

      if (lut)
        cupsImageLut(out, img->xsize * cupsImageGetDepth(img), lut);

      _cupsImagePutRow(img, 0, cinfo.output_scanline - 1, img->xsize, out);
    }
    else if (cinfo.out_color_space == JCS_RGB)
    {
      switch (img->colorspace)
      {
        default :
	    break;

        case CUPS_IMAGE_RGB :
            cupsImageRGBToRGB(in, out, img->xsize);
	    break;
        case CUPS_IMAGE_WHITE :
            cupsImageRGBToWhite(in, out, img->xsize);
            break;
        case CUPS_IMAGE_BLACK :
            cupsImageRGBToBlack(in, out, img->xsize);
            break;
        case CUPS_IMAGE_CMY :
            cupsImageRGBToCMY(in, out, img->xsize);
            break;
        case CUPS_IMAGE_CMYK :
            cupsImageRGBToCMYK(in, out, img->xsize);
            break;
      }

      if (lut)
        cupsImageLut(out, img->xsize * cupsImageGetDepth(img), lut);

      _cupsImagePutRow(img, 0, cinfo.output_scanline - 1, img->xsize, out);
    }
    else /* JCS_CMYK */
    {
      fputs("DEBUG: JCS_CMYK\n", stderr);

      switch (img->colorspace)
      {
        default :
	    break;

        case CUPS_IMAGE_WHITE :
            cupsImageCMYKToWhite(in, out, img->xsize);
            break;
        case CUPS_IMAGE_BLACK :
            cupsImageCMYKToBlack(in, out, img->xsize);
            break;
        case CUPS_IMAGE_CMY :
            cupsImageCMYKToCMY(in, out, img->xsize);
            break;
        case CUPS_IMAGE_RGB :
            cupsImageCMYKToRGB(in, out, img->xsize);
            break;
      }

      if (lut)
        cupsImageLut(out, img->xsize * cupsImageGetDepth(img), lut);

      _cupsImagePutRow(img, 0, cinfo.output_scanline - 1, img->xsize, out);
    }
  }

  free(in);
  free(out);

  jpeg_finish_decompress(&cinfo);
  jpeg_destroy_decompress(&cinfo);

  fclose(fp);

  return (0);
}
예제 #12
0
int					/* O - Exit status */
main(int  argc,				/* I - Number of command-line arguments */
     char *argv[])			/* I - Command-line arguments */
{
  cups_image_t		*img;		/* Image to print */
  cups_icspace_t	primary;	/* Primary image colorspace */
  FILE			*out;		/* Output PPM/PGM file */
  cups_ib_t		*line;		/* Line from file */
  int			y,		/* Current line */
			width,		/* Width of image */
			height,		/* Height of image */
			depth;		/* Depth of image */


  if (argc != 3)
  {
    puts("Usage: testimage filename.ext filename.[ppm|pgm]");
    return (1);
  }

  if (strstr(argv[2], ".ppm") != NULL)
    primary = CUPS_IMAGE_RGB;
  else
    primary = CUPS_IMAGE_WHITE;

  img = cupsImageOpen(argv[1], primary, CUPS_IMAGE_WHITE, 100, 0, NULL);

  if (!img)
  {
    perror(argv[1]);
    return (1);
  }

  out = fopen(argv[2], "wb");

  if (!out)
  {
    perror(argv[2]);
    cupsImageClose(img);
    return (1);
  }

  width  = cupsImageGetWidth(img);
  height = cupsImageGetHeight(img);
  depth  = cupsImageGetDepth(img);
  line   = calloc(width, depth);

  fprintf(out, "P%d\n%d\n%d\n255\n",
          cupsImageGetColorSpace(img) == CUPS_IMAGE_WHITE ? 5 : 6,
          width, height);

  for (y = 0; y < height; y ++)
  {
    cupsImageGetRow(img, 0, y, width, line);
    fwrite(line, width, depth, out);
  }

  cupsImageClose(img);
  fclose(out);

  return (0);
}
예제 #13
0
int					/* O - Read status */
_cupsImageReadPhotoCD(
    cups_image_t    *img,		/* IO - cupsImage */
    FILE            *fp,		/* I - cupsImage file */
    cups_icspace_t  primary,		/* I - Primary choice for colorspace */
    cups_icspace_t  secondary,		/* I - Secondary choice for colorspace */
    int             saturation,		/* I - Color saturation (%) */
    int             hue,		/* I - Color hue (degrees) */
    const cups_ib_t *lut)		/* I - Lookup table for gamma/brightness */
{
    int		x, y;			/* Looping vars */
    int		xdir,			/* X direction */
            xstart;			/* X starting point */
    int		bpp;			/* Bytes per pixel */
    int		pass;			/* Pass number */
    int		rotation;		/* 0 for 768x512, 1 for 512x768 */
    int		temp,			/* Adjusted luminance */
            temp2,			/* Red, green, and blue values */
            cb, cr;			/* Adjusted chroma values */
    cups_ib_t	*in,			/* Input (YCC) pixels */
                *iy,			/* Luminance */
                *icb,			/* Blue chroma */
                *icr,			/* Red chroma */
                *rgb,			/* RGB */
                *rgbptr,		/* Pointer into RGB data */
                *out;			/* Output pixels */


    (void)secondary;

    /*
     * Get the image orientation...
     */

    fseek(fp, 72, SEEK_SET);
    rotation = (getc(fp) & 63) != 8;

    /*
     * Seek to the start of the base image...
     */

    fseek(fp, 0x30000, SEEK_SET);

    /*
     * Allocate and initialize...
     */

    img->colorspace = (primary == CUPS_IMAGE_RGB_CMYK) ? CUPS_IMAGE_RGB : primary;
    img->xppi       = 128;
    img->yppi       = 128;

    if (rotation)
    {
        img->xsize = 512;
        img->ysize = 768;
    }
    else
    {
        img->xsize = 768;
        img->ysize = 512;
    }

    cupsImageSetMaxTiles(img, 0);

    bpp = cupsImageGetDepth(img);

    if ((in = malloc(768 * 3)) == NULL)
    {
        fputs("DEBUG: Unable to allocate memory!\n", stderr);
        fclose(fp);
        return (1);
    }

    if ((out = malloc(768 * bpp)) == NULL)
    {
        fputs("DEBUG: Unable to allocate memory!\n", stderr);
        fclose(fp);
        free(in);
        return (1);
    }

    if (bpp > 1)
    {
        if ((rgb = malloc(768 * 3)) == NULL)
        {
            fputs("DEBUG: Unable to allocate memory!\n", stderr);
            fclose(fp);
            free(in);
            free(out);
            return (1);
        }
    }
    else
        rgb = NULL;

    if (rotation)
    {
        xstart = 767 * bpp;
        xdir   = -2 * bpp;
    }
    else
    {
        xstart = 0;
        xdir   = 0;
    }

    /*
     * Read the image file...
     */

    for (y = 0; y < 512; y += 2)
    {
        /*
         * Grab the next two scanlines:
         *
         *     YYYYYYYYYYYYYYY...
         *     YYYYYYYYYYYYYYY...
         *     CbCbCb...CrCrCr...
         */

        if (fread(in, 1, 768 * 3, fp) < (768 * 3))
        {
            /*
             * Couldn't read a row of data - return an error!
             */

            free(in);
            free(out);

            if (bpp > 1)
                free(rgb);

            return (-1);
        }

        /*
         * Process the two scanlines...
         */

        for (pass = 0, iy = in; pass < 2; pass ++)
        {
            if (bpp == 1)
            {
                /*
                * Just extract the luminance channel from the line and put it
                * in the image...
                */

                if (primary == CUPS_IMAGE_BLACK)
                {
                    if (rotation)
                    {
                        for (rgbptr = out + xstart, x = 0; x < 768; x ++)
                            *rgbptr-- = 255 - *iy++;

                        if (lut)
                            cupsImageLut(out, 768, lut);

                        _cupsImagePutCol(img, 511 - y - pass, 0, 768, out);
                    }
                    else
                    {
                        cupsImageWhiteToBlack(iy, out, 768);

                        if (lut)
                            cupsImageLut(out, 768, lut);

                        _cupsImagePutRow(img, 0, y + pass, 768, out);
                        iy += 768;
                    }
                }
                else if (rotation)
                {
                    for (rgbptr = out + xstart, x = 0; x < 768; x ++)
                        *rgbptr-- = 255 - *iy++;

                    if (lut)
                        cupsImageLut(out, 768, lut);

                    _cupsImagePutCol(img, 511 - y - pass, 0, 768, out);
                }
                else
                {
                    if (lut)
                        cupsImageLut(iy, 768, lut);

                    _cupsImagePutRow(img, 0, y + pass, 768, iy);
                    iy += 768;
                }
            }
            else
            {
                /*
                 * Convert YCbCr to RGB...  While every pixel gets a luminance
                * value, adjacent pixels share chroma information.
                */

                cb = cr = 0.0f;

                for (x = 0, rgbptr = rgb + xstart, icb = in + 1536, icr = in + 1920;
                        x < 768;
                        x ++, iy ++, rgbptr += xdir)
                {
                    if (!(x & 1))
                    {
                        cb = (float)(*icb - 156);
                        cr = (float)(*icr - 137);
                    }

                    temp = 92241 * (*iy);

                    temp2 = (temp + 86706 * cr) / 65536;
                    if (temp2 < 0)
                        *rgbptr++ = 0;
                    else if (temp2 > 255)
                        *rgbptr++ = 255;
                    else
                        *rgbptr++ = temp2;

                    temp2 = (temp - 25914 * cb - 44166 * cr) / 65536;
                    if (temp2 < 0)
                        *rgbptr++ = 0;
                    else if (temp2 > 255)
                        *rgbptr++ = 255;
                    else
                        *rgbptr++ = temp2;

                    temp2 = (temp + 133434 * cb) / 65536;
                    if (temp2 < 0)
                        *rgbptr++ = 0;
                    else if (temp2 > 255)
                        *rgbptr++ = 255;
                    else
                        *rgbptr++ = temp2;

                    if (x & 1)
                    {
                        icb ++;
                        icr ++;
                    }
                }

                /*
                 * Adjust the hue and saturation if needed...
                */

                if (saturation != 100 || hue != 0)
                    cupsImageRGBAdjust(rgb, 768, saturation, hue);

                /*
                 * Then convert the RGB data to the appropriate colorspace and
                * put it in the image...
                */

                switch (img->colorspace)
                {
                default :
                    break;

                case CUPS_IMAGE_RGB :
                    cupsImageRGBToRGB(rgb, out, 768);
                    break;
                case CUPS_IMAGE_CMY :
                    cupsImageRGBToCMY(rgb, out, 768);
                    break;
                case CUPS_IMAGE_CMYK :
                    cupsImageRGBToCMYK(rgb, out, 768);
                    break;
                }

                if (lut)
                    cupsImageLut(out, 768 * bpp, lut);

                if (rotation)
                    _cupsImagePutCol(img, 511 - y - pass, 0, 768, out);
                else
                    _cupsImagePutRow(img, 0, y + pass, 768, out);
            }
        }
    }

    /*
     * Free memory and return...
     */

    free(in);
    free(out);
    if (bpp > 1)
        free(rgb);

    return (0);
}
예제 #14
0
cups_izoom_t *
_cupsImageZoomNew(
    cups_image_t  *img,			/* I - cupsImage to zoom */
    int           xc0,			/* I - Upper-lefthand corner */
    int           yc0,			/* I - ... */
    int           xc1,			/* I - Lower-righthand corner */
    int           yc1,			/* I - ... */
    int           xsize,		/* I - Final width of image */
    int           ysize,		/* I - Final height of image */
    int           rotated,		/* I - Non-zero if image is rotated 90 degs */
    cups_iztype_t type)			/* I - Zoom type */
{
  cups_izoom_t	*z;			/* New zoom record */
  int		flip;			/* Flip on X axis? */


  if (xsize > CUPS_IMAGE_MAX_WIDTH ||
      ysize > CUPS_IMAGE_MAX_HEIGHT ||
      (xc1 - xc0) > CUPS_IMAGE_MAX_WIDTH ||
      (yc1 - yc0) > CUPS_IMAGE_MAX_HEIGHT)
    return (NULL);		/* Protect against integer overflow */

  if ((z = (cups_izoom_t *)calloc(1, sizeof(cups_izoom_t))) == NULL)
    return (NULL);

  z->img     = img;
  z->row     = 0;
  z->depth   = cupsImageGetDepth(img);
  z->rotated = rotated;
  z->type    = type;

  if (xsize < 0)
  {
    flip  = 1;
    xsize = -xsize;
  }
  else
  {
    flip  = 0;
  }

  if (rotated)
  {
    z->xorig   = xc1;
    z->yorig   = yc0;
    z->width   = yc1 - yc0 + 1;
    z->height  = xc1 - xc0 + 1;
    z->xsize   = xsize;
    z->ysize   = ysize;
    z->xmod    = z->width % z->xsize;
    z->xstep   = z->width / z->xsize;
    z->xincr   = 1;
    z->ymod    = z->height % z->ysize;
    z->ystep   = z->height / z->ysize;
    z->yincr   = 1;
    z->instep  = z->xstep * z->depth;
    z->inincr  = /* z->xincr * */ z->depth; /* z->xincr is always 1 */

    if (z->width < img->ysize)
      z->xmax = z->width;
    else
      z->xmax = z->width - 1;

    if (z->height < img->xsize)
      z->ymax = z->height;
    else
      z->ymax = z->height - 1;
  }
  else
  {
    z->xorig   = xc0;
    z->yorig   = yc0;
    z->width   = xc1 - xc0 + 1;
    z->height  = yc1 - yc0 + 1;
    z->xsize   = xsize;
    z->ysize   = ysize;
    z->xmod    = z->width % z->xsize;
    z->xstep   = z->width / z->xsize;
    z->xincr   = 1;
    z->ymod    = z->height % z->ysize;
    z->ystep   = z->height / z->ysize;
    z->yincr   = 1;
    z->instep  = z->xstep * z->depth;
    z->inincr  = /* z->xincr * */ z->depth; /* z->xincr is always 1 */

    if (z->width < img->xsize)
      z->xmax = z->width;
    else
      z->xmax = z->width - 1;

    if (z->height < img->ysize)
      z->ymax = z->height;
    else
      z->ymax = z->height - 1;
  }

  if (flip)
  {
    z->instep = -z->instep;
    z->inincr = -z->inincr;
  }

  if ((z->rows[0] = (cups_ib_t *)malloc(z->xsize * z->depth)) == NULL)
  {
    free(z);
    return (NULL);
  }

  if ((z->rows[1] = (cups_ib_t *)malloc(z->xsize * z->depth)) == NULL)
  {
    free(z->rows[0]);
    free(z);
    return (NULL);
  }

  if ((z->in = (cups_ib_t *)malloc(z->width * z->depth)) == NULL)
  {
    free(z->rows[0]);
    free(z->rows[1]);
    free(z);
    return (NULL);
  }

  return (z);
}