1// This may look like C code, but it is really -*- C++ -*-
2//
3// Copyright Bob Friesenhahn, 1999, 2000, 2001, 2002, 2003
4// Copyright Dirk Lemstra 2013-2015
5//
6// Pixels Implementation
7//
8
9#define MAGICKCORE_IMPLEMENTATION  1
10#define MAGICK_PLUSPLUS_IMPLEMENTATION 1
11
12#include <cstring>
13#include "Magick++/Include.h"
14#include <string> // This is here to compile with Visual C++
15#include "Magick++/Thread.h"
16#include "Magick++/Exception.h"
17#include "Magick++/Pixels.h"
18
19Magick::Pixels::Pixels(Magick::Image &image_)
20  : _image(image_),
21    _x(0),
22    _y(0),
23    _columns(0),
24    _rows(0)
25{
26  GetPPException;
27    _view=AcquireVirtualCacheView(image_.image(),exceptionInfo),
28  ThrowPPException(image_.quiet());
29}
30
31Magick::Pixels::~Pixels(void)
32{
33  if (_view)
34    _view=DestroyCacheView(_view);
35}
36
37Magick::Quantum* Magick::Pixels::get(const ssize_t x_,const ssize_t y_,
38  const size_t columns_,const size_t rows_)
39{
40  _x=x_;
41  _y=y_;
42  _columns=columns_;
43  _rows=rows_;
44
45  GetPPException;
46  Quantum* pixels=GetCacheViewAuthenticPixels(_view,x_,y_,columns_,rows_,
47    exceptionInfo);
48  ThrowPPException(_image.quiet());
49
50  return pixels;
51}
52
53const Magick::Quantum* Magick::Pixels::getConst(const ssize_t x_,
54  const ssize_t y_,const size_t columns_,const size_t rows_)
55{
56  _x=x_;
57  _y=y_;
58  _columns=columns_;
59  _rows=rows_;
60
61  GetPPException;
62  const Quantum* pixels=GetCacheViewVirtualPixels(_view,x_,y_,columns_,rows_,
63    exceptionInfo);
64  ThrowPPException(_image.quiet());
65
66  return pixels;
67}
68
69ssize_t Magick::Pixels::offset(PixelChannel channel) const
70{
71  if (_image.constImage()->channel_map[channel].traits == UndefinedPixelTrait)
72    return -1;
73  return _image.constImage()->channel_map[channel].offset;
74}
75
76Magick::Quantum* Magick::Pixels::set(const ssize_t x_,const ssize_t y_,
77  const size_t columns_,const size_t rows_)
78{
79  _x=x_;
80  _y=y_;
81  _columns=columns_;
82  _rows=rows_;
83
84  GetPPException;
85  Quantum* pixels=QueueCacheViewAuthenticPixels(_view,x_,y_,columns_,rows_,
86    exceptionInfo);
87  ThrowPPException(_image.quiet());
88
89  return pixels;
90}
91
92void Magick::Pixels::sync(void)
93{
94  GetPPException;
95  (void) SyncCacheViewAuthenticPixels(_view,exceptionInfo);
96  ThrowPPException(_image.quiet());
97}
98
99// Return pixel colormap index array
100/*
101Magick::void* Magick::Pixels::metacontent(void)
102{
103  void* pixel_metacontent=GetCacheViewAuthenticMetacontent(_view);
104
105  if (!pixel_metacontent)
106    _image.throwImageException();
107
108  return pixel_metacontent;
109}
110*/
111
112Magick::PixelData::PixelData(Magick::Image &image_,std::string map_,
113  const StorageType type_)
114{
115  init(image_,0,0,image_.columns(),image_.rows(),map_,type_);
116}
117
118Magick::PixelData::PixelData(Magick::Image &image_,const ::ssize_t x_,
119  const ::ssize_t y_,const size_t width_,const size_t height_,std::string map_,
120  const StorageType type_)
121{
122  init(image_,x_,y_,width_,height_,map_,type_);
123}
124
125Magick::PixelData::~PixelData(void)
126{
127  relinquish();
128}
129
130const void *Magick::PixelData::data(void) const
131{
132  return(_data);
133}
134
135::ssize_t Magick::PixelData::length(void) const
136{
137  return(_length);
138}
139
140::ssize_t Magick::PixelData::size(void) const
141{
142  return(_size);
143}
144
145void Magick::PixelData::init(Magick::Image &image_,const ::ssize_t x_,
146  const ::ssize_t y_,const size_t width_,const size_t height_,
147  std::string map_,const StorageType type_)
148{
149  size_t
150    size;
151
152  _data=(void *) NULL;
153  _length=0;
154  _size=0;
155  if ((x_ < 0) || (width_ == 0) || (y_ < 0) || (height_ == 0) ||
156      (x_ > (ssize_t) image_.columns()) || ((width_ + x_) > image_.columns())
157      || (y_ > (ssize_t) image_.rows()) || ((height_ + y_) > image_.rows())
158      || (map_.length() == 0))
159    return;
160
161  switch(type_)
162  {
163    case CharPixel:
164      size=sizeof(unsigned char);
165      break;
166    case DoublePixel:
167      size=sizeof(double);
168      break;
169    case FloatPixel:
170      size=sizeof(float);
171      break;
172    case LongPixel:
173      size=sizeof(unsigned int);
174      break;
175    case LongLongPixel:
176      size=sizeof(MagickSizeType);
177      break;
178    case QuantumPixel:
179      size=sizeof(Quantum);
180      break;
181    case ShortPixel:
182      size=sizeof(unsigned short);
183      break;
184    default:
185      throwExceptionExplicit(MagickCore::OptionError,"Invalid type");
186      return;
187  }
188
189  _length=width_*height_*map_.length();
190  _size=_length*size;
191  _data=AcquireMagickMemory(_size);
192
193  GetPPException;
194  MagickCore::ExportImagePixels(image_.image(),x_,y_,width_,height_,
195    map_.c_str(),type_,_data,exceptionInfo);
196  if (exceptionInfo->severity != MagickCore::UndefinedException)
197    relinquish();
198  ThrowPPException(image_.quiet());
199}
200
201void Magick::PixelData::relinquish(void) throw()
202{
203  if (_data != (void *)NULL)
204    _data=RelinquishMagickMemory(_data);
205  _length=0;
206  _size=0;
207}
208