Exemplo n.º 1
0
static jas_image_t *jpg_mkimage(j_decompress_ptr cinfo)
{
    jas_image_t *image;
    int cmptno;
    jas_image_cmptparm_t cmptparm;
    int numcmpts;

    image = 0;
    numcmpts = cinfo->output_components;
    if (!(image = jas_image_create0())) {
        goto error;
    }
    for (cmptno = 0; cmptno < numcmpts; ++cmptno) {
        cmptparm.tlx = 0;
        cmptparm.tly = 0;
        cmptparm.hstep = 1;
        cmptparm.vstep = 1;
        cmptparm.width = cinfo->image_width;
        cmptparm.height = cinfo->image_height;
        cmptparm.prec = 8;
        cmptparm.sgnd = false;
        if (jas_image_addcmpt(image, cmptno, &cmptparm)) {
            goto error;
        }
    }

    if (numcmpts == 3) {
        jas_image_setclrspc(image, JAS_CLRSPC_SRGB);
        jas_image_setcmpttype(image, 0,
          JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_R));
        jas_image_setcmpttype(image, 1,
          JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_G));
        jas_image_setcmpttype(image, 2,
          JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_B));
    } else {
        jas_image_setclrspc(image, JAS_CLRSPC_SGRAY);
        jas_image_setcmpttype(image, 0,
          JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_GRAY_Y));
    }

    return image;

error:
    if (image) {
        jas_image_destroy(image);
    }
    return 0;
}
Exemplo n.º 2
0
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
%   W r i t e J P 2 I m a g e                                                 %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  Method WriteJP2Image writes an image in the JPEG 2000 image format.
%
%  JP2 support originally written by Nathan Brown, [email protected]
%
%  The format of the WriteJP2Image method is:
%
%      MagickPassFail WriteJP2Image(const ImageInfo *image_info,Image *image)
%
%  A description of each parameter follows.
%
%    o status: Method WriteJP2Image return MagickTrue if the image is written.
%      MagickFalse is returned is there is a memory shortage or if the image file
%      fails to write.
%
%    o image_info: Specifies a pointer to a ImageInfo structure.
%
%    o image:  A pointer to an Image structure.
%
%
*/
static MagickPassFail
WriteJP2Image(const ImageInfo *image_info,Image *image)
{
  char
    magick[MaxTextExtent],
    option_keyval[MaxTextExtent],
    *options = NULL;

  int
    format;

  long
    y;

  jas_image_cmptparm_t
    component_info;

  jas_image_t
    *jp2_image;

  jas_matrix_t
    *jp2_pixels;

  jas_stream_t
    *jp2_stream;

  register const PixelPacket
    *p;

  register int
    x;

  unsigned int
    rate_specified=False,
    status;

  int
    component,
    number_components;

  unsigned short
    *lut;

  ImageCharacteristics
    characteristics;

  /*
    Open image file.
  */
  assert(image_info != (const ImageInfo *) NULL);
  assert(image_info->signature == MagickSignature);
  assert(image != (Image *) NULL);
  assert(image->signature == MagickSignature);
  status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
  if (status == False)
    ThrowWriterException(FileOpenError,UnableToOpenFile,image);

  /*
    Ensure that image is in RGB space.
  */
  (void) TransformColorspace(image,RGBColorspace);

  /*
    Analyze image to be written.
  */
  if (!GetImageCharacteristics(image,&characteristics,
                               (OptimizeType == image_info->type),
                               &image->exception))
    {
      CloseBlob(image);
      return MagickFail;
    }

  /*
    Obtain a JP2 stream.
  */
  jp2_stream=JP2StreamManager(image);
  if (jp2_stream == (jas_stream_t *) NULL)
    ThrowWriterException(DelegateError,UnableToManageJP2Stream,image);
  number_components=image->matte ? 4 : 3;
  if ((image_info->type != TrueColorType) &&
      (characteristics.grayscale))
    number_components=1;

  jp2_image=jas_image_create0();
  if (jp2_image == (jas_image_t *) NULL)
    ThrowWriterException(DelegateError,UnableToCreateImage,image);

  for (component=0; component < number_components; component++)
  {
    (void) memset((void *)&component_info,0,sizeof(jas_image_cmptparm_t));
    component_info.tlx=0; /* top left x ordinate */
    component_info.tly=0; /* top left y ordinate */
    component_info.hstep=1; /* horizontal pixels per step */
    component_info.vstep=1; /* vertical pixels per step */
    component_info.width=(unsigned int) image->columns;
    component_info.height=(unsigned int) image->rows;
    component_info.prec=(unsigned int) Max(2,Min(image->depth,16)); /* bits in range */
    component_info.sgnd = false;  /* range is signed value? */

    if (jas_image_addcmpt(jp2_image, component,&component_info)) {
      jas_image_destroy(jp2_image);
      ThrowWriterException(DelegateError,UnableToCreateImageComponent,image);
    }
  }

  /*
    Allocate and compute LUT.
  */
  {
    unsigned long
      i,
      max_value;

    double
      scale_to_component;

    lut=MagickAllocateArray(unsigned short *,MaxMap+1,sizeof(*lut));
    if (lut == (unsigned short *) NULL)
      {
	jas_image_destroy(jp2_image);
	ThrowWriterException(ResourceLimitError,MemoryAllocationFailed,image);
      }

    max_value=MaxValueGivenBits(component_info.prec);
    scale_to_component=max_value/MaxRGBDouble;
    for(i=0; i <= MaxMap; i++)
	lut[i]=scale_to_component*i+0.5;
  }

  if (number_components == 1)
    {
      /* FIXME: If image has an attached ICC profile, then the profile
         should be transferred and the image colorspace set to
         JAS_CLRSPC_GENGRAY */
      /* sRGB Grayscale */
      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
        "Setting SGRAY colorspace");
      jas_image_setclrspc(jp2_image, JAS_CLRSPC_SGRAY);
      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
        "Setting GRAY channel to channel 0");
      jas_image_setcmpttype(jp2_image,0,
        JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_GRAY_Y));
    }
  else
    {
      /* FIXME: If image has an attached ICC profile, then the profile
         should be transferred and the image colorspace set to
         JAS_CLRSPC_GENRGB */

      /* sRGB */
      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
        "Setting SRGB colorspace");
      jas_image_setclrspc(jp2_image, JAS_CLRSPC_SRGB);
      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
        "Setting RED channel to channel 0");
      jas_image_setcmpttype(jp2_image,0,
        JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_R));
      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
        "Setting GREEN channel to channel 1");
      jas_image_setcmpttype(jp2_image,1,
        JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_G));
      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
        "Setting BLUE channel to channel 2");
      jas_image_setcmpttype(jp2_image,2,
        JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_B));
      if (number_components == 4 )
        {
          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
            "Setting OPACITY channel to channel 3");
          jas_image_setcmpttype(jp2_image,3,
            JAS_IMAGE_CT_COLOR(JAS_IMAGE_CT_OPACITY));
        }
    }
  /*
    Convert to JPEG 2000 pixels.
  */
  jp2_pixels=jas_matrix_create(1,(unsigned int) image->columns);
  if (jp2_pixels == (jas_matrix_t *) NULL)
    {
      MagickFreeMemory(lut);
      jas_image_destroy(jp2_image);
      ThrowWriterException(ResourceLimitError,MemoryAllocationFailed,image);
    }

  for (y=0; y < (long) image->rows; y++)
  {
    p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception);
    if (p == (const PixelPacket *) NULL)
      break;
    if (number_components == 1)
      {
	for (x=0; x < (long) image->columns; x++)
	  jas_matrix_setv(jp2_pixels,x,lut[ScaleQuantumToMap(PixelIntensityToQuantum(&p[x]))]);
	(void) jas_image_writecmpt(jp2_image,0,0,(unsigned int) y,
				   (unsigned int) image->columns,1,jp2_pixels);
      }
    else
      {
	for (x=0; x < (long) image->columns; x++)
	  jas_matrix_setv(jp2_pixels,x,lut[ScaleQuantumToMap(p[x].red)]);
	(void) jas_image_writecmpt(jp2_image,0,0,(unsigned int) y,
				   (unsigned int) image->columns,1,jp2_pixels);

	for (x=0; x < (long) image->columns; x++)
	  jas_matrix_setv(jp2_pixels,x,lut[ScaleQuantumToMap(p[x].green)]);
	(void) jas_image_writecmpt(jp2_image,1,0,(unsigned int) y,
				   (unsigned int) image->columns,1,jp2_pixels);

	for (x=0; x < (long) image->columns; x++)
	  jas_matrix_setv(jp2_pixels,x,lut[ScaleQuantumToMap(p[x].blue)]);
	(void) jas_image_writecmpt(jp2_image,2,0,(unsigned int) y,
				   (unsigned int) image->columns,1,jp2_pixels);

	if (number_components > 3)
	  for (x=0; x < (long) image->columns; x++)
	    jas_matrix_setv(jp2_pixels,x,lut[ScaleQuantumToMap(MaxRGB-p[x].opacity)]);
	(void) jas_image_writecmpt(jp2_image,3,0,(unsigned int) y,
				   (unsigned int) image->columns,1,jp2_pixels);
      }
    if (image->previous == (Image *) NULL)
      if (QuantumTick(y,image->rows))
        if (!MagickMonitorFormatted(y,image->rows,&image->exception,
                                    SaveImageText,image->filename,
				    image->columns,image->rows))
          break;
  }
  (void) strlcpy(magick,image_info->magick,MaxTextExtent);
  /*
    J2C is an alias for JPC but Jasper only supports "JPC".
  */
  if (LocaleCompare(magick,"j2c") == 0)
    (void) strlcpy(magick,"jpc",sizeof(magick));
  LocaleLower(magick);
  format=jas_image_strtofmt(magick);

  /*
    Support passing Jasper options.
  */
  {
    const char
      **option_name;

    static const char *jasper_options[] =
      {
        "imgareatlx",
        "imgareatly",
        "tilegrdtlx",
        "tilegrdtly",
        "tilewidth",
        "tileheight",
        "prcwidth",
        "prcheight",
        "cblkwidth",
        "cblkheight",
        "mode",
        "ilyrrates",
        "prg",
        "nomct",
        "numrlvls",
        "sop",
        "eph",
        "lazy",
        "rate",
        "termall",
        "segsym",
        "vcausal",
        "pterm",
        "resetprob",
        "numgbits",
        NULL
      };
    for (option_name = jasper_options; *option_name != NULL; option_name++)
      {
        const char
          *value;

        if ((value=AccessDefinition(image_info,"jp2",*option_name)) != NULL)
          {
            if(LocaleCompare(*option_name,"rate") == 0)
              rate_specified=True;
            FormatString(option_keyval,"%s=%.1024s ",*option_name,value);
            ConcatenateString(&options,option_keyval);
          }
      }
  }
  /*
    Provide an emulation of IJG JPEG "quality" by default.
  */
  if (rate_specified == False)
    {
      double
        rate=1.0;
      
      /*
        A rough approximation to JPEG v1 quality using JPEG-2000.
        Default "quality" 75 results in a request for 16:1 compression, which
        results in image sizes approximating that of JPEG v1.
      */
      if ((image_info->quality < 99.5) && (image->rows*image->columns > 2500))
        {
          double
            header_size,
            current_size,
            target_size,
            d;
          
          d=115-image_info->quality;  /* Best number is 110-115 */
          rate=100.0/(d*d);
          header_size=550.0; /* Base file size. */
          header_size+=(number_components-1)*142; /* Additional components */
          /* FIXME: Need to account for any ICC profiles here */
          
          current_size=(double)((image->rows*image->columns*image->depth)/8)*
            number_components;
          target_size=(current_size*rate)+header_size;
          rate=target_size/current_size;
        }
      FormatString(option_keyval,"%s=%g ","rate",rate);
      ConcatenateString(&options,option_keyval);
      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
        "Compression rate: %g (%3.2f:1)",rate,1.0/rate);
    }
  if (options)
    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
       "Jasper options: \"%s\"", options);

  (void) LogMagickEvent(CoderEvent,GetMagickModule(),"Encoding image");
  status=jas_image_encode(jp2_image,jp2_stream,format,options);
  (void) jas_stream_close(jp2_stream);
  MagickFreeMemory(options);
  MagickFreeMemory(lut);
  jas_matrix_destroy(jp2_pixels);
  jas_image_destroy(jp2_image);
  if (status)
    ThrowWriterException(DelegateError,UnableToEncodeImageFile,image);
  return(True);
}
Exemplo n.º 3
0
void JPCInstance::CreateImage( const ImageInfo& info )
{
   CheckOpenStream( !m_path.IsEmpty(), "CreateImage" );

   InitJasPer();

   if ( !info.IsValid() )
      JP2KERROR( "Invalid image parameters in JPEG2000 file creation" );

   if ( info.colorSpace != ColorSpace::RGB && info.colorSpace != ColorSpace::Gray )
      JP2KERROR( "Unsupported color space in JPEG2000 file creation" );

   if ( m_options.bitsPerSample != 8 )
      if ( m_jp2Options.lossyCompression || m_options.bitsPerSample < 8 )
         m_options.bitsPerSample = 8;
      else if ( m_options.bitsPerSample != 16 )
         m_options.bitsPerSample = 16;

   if ( m_jp2CMProfile == nullptr )
      m_options.embedICCProfile = false;

   m_options.ieeefpSampleFormat = m_options.complexSample = false;

   IsoString path8 =
#ifdef __PCL_WINDOWS
      File::UnixPathToWindows( m_path ).ToMBS();
#else
      m_path.ToUTF8();
#endif
   m_jp2Stream = jas_stream_fopen( path8.c_str(), "wb" );
   if ( m_jp2Stream == nullptr )
      JP2KERROR( "Unable to create JPEG2000 file" );

   m_jp2Image = jas_image_create0();
   if ( m_jp2Image == nullptr )
      JP2KERROR( "Unable to create JPEG2000 image" );

   for ( int c = 0; c < info.numberOfChannels; ++c )
   {
      jas_image_cmptparm_t p;
      ::memset( &p, 0, sizeof( jas_image_cmptparm_t ) );
      p.tlx = p.tly = 0;                  // top-left corner position
      p.hstep = p.vstep = 1;              // coordinate grid step sizes
      p.width = info.width;               // width in pixels
      p.height = info.height;             // height in pixels
      p.prec = m_options.bitsPerSample;   // bit depth: 8 or 16 bits
      p.sgnd = m_jp2Options.signedSample; // signed or unsigned samples

      if ( jas_image_addcmpt( m_jp2Image, c, &p ) != 0 )
         JP2KERROR( "Unable to create JPEG2000 image component" );
   }

   if ( info.colorSpace == ColorSpace::Gray )
   {
      jas_image_setclrspc( m_jp2Image, m_options.embedICCProfile ? JAS_CLRSPC_GENGRAY : JAS_CLRSPC_SGRAY );

      jas_image_setcmpttype( m_jp2Image, 0, JAS_IMAGE_CT_COLOR( JAS_CLRSPC_CHANIND_GRAY_Y ) );

      if ( info.numberOfChannels > 1 )
         jas_image_setcmpttype( m_jp2Image, 1, JAS_IMAGE_CT_COLOR( JAS_IMAGE_CT_OPACITY ) );
   }
   else
   {
      jas_image_setclrspc( m_jp2Image, m_options.embedICCProfile ? JAS_CLRSPC_GENRGB : JAS_CLRSPC_SRGB );

      jas_image_setcmpttype( m_jp2Image, 0, JAS_IMAGE_CT_COLOR( JAS_CLRSPC_CHANIND_RGB_R ) );
      jas_image_setcmpttype( m_jp2Image, 1, JAS_IMAGE_CT_COLOR( JAS_CLRSPC_CHANIND_RGB_G ) );
      jas_image_setcmpttype( m_jp2Image, 2, JAS_IMAGE_CT_COLOR( JAS_CLRSPC_CHANIND_RGB_B ) );

      if ( info.numberOfChannels > 3 )
         jas_image_setcmpttype( m_jp2Image, 3, JAS_IMAGE_CT_COLOR( JAS_IMAGE_CT_OPACITY ) );
   }

   if ( m_options.embedICCProfile )
      jas_image_setcmprof( m_jp2Image, m_jp2CMProfile );

   if ( m_jp2Options.resolutionData )
   {
      m_jp2Image->rescm_ = m_options.metricResolution;
      m_jp2Image->hdispres_ = RoundI( m_options.xResolution );
      m_jp2Image->vdispres_ = RoundI( m_options.yResolution );
   }
}