Pixels.cpp revision a7c1e5c12b9aec82327d2cae6ff71712c4b875d4
13ed852eea50f9d4cd633efb8c2b054b8e33c253cristy// This may look like C code, but it is really -*- C++ -*-
23ed852eea50f9d4cd633efb8c2b054b8e33c253cristy//
33ed852eea50f9d4cd633efb8c2b054b8e33c253cristy// Copyright Bob Friesenhahn, 1999, 2000, 2001, 2002, 2003
43ed852eea50f9d4cd633efb8c2b054b8e33c253cristy//
53ed852eea50f9d4cd633efb8c2b054b8e33c253cristy// Pixels Implementation
63ed852eea50f9d4cd633efb8c2b054b8e33c253cristy//
73ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
83ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define MAGICKCORE_IMPLEMENTATION  1
93ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define MAGICK_PLUSPLUS_IMPLEMENTATION 1
103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1105065f4c09f42c5cd3b5720e5b52c0c3928d2b2bcristy#include <cstring>
123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "Magick++/Include.h"
133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include <string> // This is here to compile with Visual C++
143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "Magick++/Thread.h"
153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "Magick++/Exception.h"
163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "Magick++/Pixels.h"
173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
186f0033cdfd3b04c652521d2ff9c375366972225adirkMagick::Pixels::Pixels(Magick::Image &image_)
193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  : _image(image_),
2046ff2676b1044ea4101ac7a59b83289cd8f6cfdacristy    _view(AcquireVirtualCacheView(_image.image(),&_exception)),
213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    _x(0),
223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    _y(0),
233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    _columns(0),
243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    _rows(0)
253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
266f0033cdfd3b04c652521d2ff9c375366972225adirk  GetExceptionInfo(&_exception);
273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (!_view)
291940fe06f035ea32a4ec4df61f6897396877aa3cdirk    throwExceptionExplicit(OptionError,"Empty view detected.");
303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
326f0033cdfd3b04c652521d2ff9c375366972225adirkMagick::Pixels::~Pixels(void)
333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
346f0033cdfd3b04c652521d2ff9c375366972225adirk  if (_view)
356f0033cdfd3b04c652521d2ff9c375366972225adirk    _view=DestroyCacheView(_view);
363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
376f0033cdfd3b04c652521d2ff9c375366972225adirk  (void) DestroyExceptionInfo(&_exception);
383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
406f0033cdfd3b04c652521d2ff9c375366972225adirkMagick::Quantum* Magick::Pixels::get(const ssize_t x_,const ssize_t y_,
416f0033cdfd3b04c652521d2ff9c375366972225adirk  const size_t columns_,const size_t rows_)
423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
436f0033cdfd3b04c652521d2ff9c375366972225adirk  _x=x_;
446f0033cdfd3b04c652521d2ff9c375366972225adirk  _y=y_;
456f0033cdfd3b04c652521d2ff9c375366972225adirk  _columns=columns_;
466f0033cdfd3b04c652521d2ff9c375366972225adirk  _rows=rows_;
473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
486f0033cdfd3b04c652521d2ff9c375366972225adirk  Quantum* pixels=GetCacheViewAuthenticPixels(_view,x_,y_,columns_,rows_,
496f0033cdfd3b04c652521d2ff9c375366972225adirk    &_exception);
506f0033cdfd3b04c652521d2ff9c375366972225adirk
516f0033cdfd3b04c652521d2ff9c375366972225adirk  if (!pixels)
526f0033cdfd3b04c652521d2ff9c375366972225adirk    throwException(_exception);
533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return pixels;
553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
576f0033cdfd3b04c652521d2ff9c375366972225adirkconst Magick::Quantum* Magick::Pixels::getConst(const ssize_t x_,
586f0033cdfd3b04c652521d2ff9c375366972225adirk  const ssize_t y_,const size_t columns_,const size_t rows_)
593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
606f0033cdfd3b04c652521d2ff9c375366972225adirk  _x=x_;
616f0033cdfd3b04c652521d2ff9c375366972225adirk  _y=y_;
626f0033cdfd3b04c652521d2ff9c375366972225adirk  _columns=columns_;
636f0033cdfd3b04c652521d2ff9c375366972225adirk  _rows=rows_;
643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
656f0033cdfd3b04c652521d2ff9c375366972225adirk  const Quantum* pixels=GetCacheViewVirtualPixels(_view,x_,y_,columns_,rows_,
666f0033cdfd3b04c652521d2ff9c375366972225adirk    &_exception);
673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
686f0033cdfd3b04c652521d2ff9c375366972225adirk  if (!pixels)
696f0033cdfd3b04c652521d2ff9c375366972225adirk    throwException(_exception);
703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
716f0033cdfd3b04c652521d2ff9c375366972225adirk  return pixels;
723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7400bcb8c08b29ab70e1d24a21ccfe8515baa2af6cdirkssize_t Magick::Pixels::offset(PixelChannel channel) const
7500bcb8c08b29ab70e1d24a21ccfe8515baa2af6cdirk{
7600bcb8c08b29ab70e1d24a21ccfe8515baa2af6cdirk  if (_image.constImage()->channel_map[channel].traits == UndefinedPixelTrait)
7700bcb8c08b29ab70e1d24a21ccfe8515baa2af6cdirk    return -1;
7800bcb8c08b29ab70e1d24a21ccfe8515baa2af6cdirk  return _image.constImage()->channel_map[channel].offset;
7900bcb8c08b29ab70e1d24a21ccfe8515baa2af6cdirk}
8000bcb8c08b29ab70e1d24a21ccfe8515baa2af6cdirk
816f0033cdfd3b04c652521d2ff9c375366972225adirkMagick::Quantum* Magick::Pixels::set(const ssize_t x_,const ssize_t y_,
826f0033cdfd3b04c652521d2ff9c375366972225adirk  const size_t columns_,const size_t rows_)
833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
846f0033cdfd3b04c652521d2ff9c375366972225adirk  _x=x_;
856f0033cdfd3b04c652521d2ff9c375366972225adirk  _y=y_;
866f0033cdfd3b04c652521d2ff9c375366972225adirk  _columns=columns_;
876f0033cdfd3b04c652521d2ff9c375366972225adirk  _rows=rows_;
886f0033cdfd3b04c652521d2ff9c375366972225adirk
896f0033cdfd3b04c652521d2ff9c375366972225adirk  Quantum* pixels=QueueCacheViewAuthenticPixels(_view,x_,y_,columns_,rows_,
906f0033cdfd3b04c652521d2ff9c375366972225adirk    &_exception);
916f0033cdfd3b04c652521d2ff9c375366972225adirk
926f0033cdfd3b04c652521d2ff9c375366972225adirk  if (!pixels)
936f0033cdfd3b04c652521d2ff9c375366972225adirk    throwException(_exception);
946f0033cdfd3b04c652521d2ff9c375366972225adirk
956f0033cdfd3b04c652521d2ff9c375366972225adirk  return pixels;
963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
976f0033cdfd3b04c652521d2ff9c375366972225adirk
986f0033cdfd3b04c652521d2ff9c375366972225adirkvoid Magick::Pixels::sync(void)
993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
1006f0033cdfd3b04c652521d2ff9c375366972225adirk  if(!SyncCacheViewAuthenticPixels(_view,&_exception))
1016f0033cdfd3b04c652521d2ff9c375366972225adirk    throwException(_exception);
1023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
1033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy// Return pixel colormap index array
1054c08aed51c5899665ade97263692328eea4af106cristy/*
1066f0033cdfd3b04c652521d2ff9c375366972225adirkMagick::void* Magick::Pixels::metacontent(void)
1073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
1086f0033cdfd3b04c652521d2ff9c375366972225adirk  void* pixel_metacontent=GetCacheViewAuthenticMetacontent(_view);
1093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1106f0033cdfd3b04c652521d2ff9c375366972225adirk  if (!pixel_metacontent)
1113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    _image.throwImageException();
1123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1134c08aed51c5899665ade97263692328eea4af106cristy  return pixel_metacontent;
1143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
1154c08aed51c5899665ade97263692328eea4af106cristy*/
116a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk
117a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirkMagick::PixelData::PixelData(Magick::Image &image_,std::string map_,
118a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk  const StorageType type_)
119a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk{
120a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk  init(image_,0,0,image_.columns(),image_.rows(),map_,type_);
121a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk}
122a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk
123a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirkMagick::PixelData::PixelData(Magick::Image &image_,const ::ssize_t x_,
124a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk  const ::ssize_t y_,const size_t width_,const size_t height_,std::string map_,
125a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk  const StorageType type_)
126a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk{
127a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk  init(image_,x_,y_,width_,height_,map_,type_);
128a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk}
129a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk
130a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirkMagick::PixelData::~PixelData(void)
131a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk{
132a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk  relinquish();
133a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk}
134a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk
135a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirkconst void *Magick::PixelData::data(void) const
136a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk{
137a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk  return(_data);
138a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk}
139a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk
140a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirkconst ::ssize_t Magick::PixelData::length(void) const
141a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk{
142a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk  return(_length);
143a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk}
144a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk
145a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirkconst ::ssize_t Magick::PixelData::size(void) const
146a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk{
147a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk  return(_size);
148a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk}
149a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk
150a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk
151a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirkvoid Magick::PixelData::init(Magick::Image &image_,const ::ssize_t x_,
152a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk  const ::ssize_t y_,const size_t width_,const size_t height_,
153a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk  std::string map_,const StorageType type_)
154a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk{
155a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk  size_t
156a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk    size;
157a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk
158a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk  _data=(void *) NULL;
159a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk  _length=0;
160a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk  _size=0;
161a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk  if ((x_ < 0) || (width_ < 0) || (y_ < 0) || (height_ < 0) ||
162a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk      (x_ > image_.columns()) || (width_ + x_ > image_.columns()) ||
163a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk      (y_ > image_.rows()) || (height_ + y_ > image_.rows()) ||
164a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk      (map_.length() == 0))
165a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk    return;
166a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk
167a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk  switch(type_)
168a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk  {
169a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk    case CharPixel:
170a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk      size=sizeof(unsigned char);
171a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk      break;
172a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk    case DoublePixel:
173a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk      size=sizeof(double);
174a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk      break;
175a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk    case FloatPixel:
176a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk      size=sizeof(float);
177a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk      break;
178a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk    case LongPixel:
179a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk      size=sizeof(unsigned int);
180a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk      break;
181a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk    case LongLongPixel:
182a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk      size=sizeof(MagickSizeType);
183a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk      break;
184a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk    case QuantumPixel:
185a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk      size=sizeof(Quantum);
186a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk      break;
187a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk    case ShortPixel:
188a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk      size=sizeof(unsigned short);
189a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk      break;
190a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk    default:
191a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk      throwExceptionExplicit(OptionError,"Invalid type");
192a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk      return;
193a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk  }
194a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk
195a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk  _length=width_*height_*map_.length();
196a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk  _size=_length*size;
197a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk  _data=AcquireMagickMemory(_size);
198a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk
199a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk  GetPPException;
200a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk  MagickCore::ExportImagePixels(image_.constImage(),x_,y_,width_,height_,
201a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk    map_.c_str(),type_,_data,&exceptionInfo);
202a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk  if (exceptionInfo.severity != UndefinedException)
203a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk    relinquish();
204a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk  ThrowPPException;
205a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk}
206a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk
207a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirkvoid Magick::PixelData::relinquish(void) throw()
208a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk{
209a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk  if (_data != (void *)NULL)
210a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk    _data=RelinquishMagickMemory(_data);
211a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk  _length=0;
212a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk  _size=0;
213a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk}