File: image.cpp

package info (click to toggle)
nurbs%2B%2B 3.0.11-4
  • links: PTS
  • area: main
  • in suites: sarge
  • size: 4,012 kB
  • ctags: 3,023
  • sloc: cpp: 26,461; sh: 16,989; makefile: 317; ansic: 27
file content (371 lines) | stat: -rw-r--r-- 9,401 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
/*=============================================================================
        File: image.cpp
     Purpose:
    Revision: $Id: image.cpp,v 1.2 2002/05/13 21:07:45 philosophil Exp $
  Created by:    Philippe Lavoie          (3 Oct, 1996)
 Modified by: 

 Copyright notice:
          Copyright (C) 1996-1997 Philippe Lavoie
 
	  This library is free software; you can redistribute it and/or
	  modify it under the terms of the GNU Library General Public
	  License as published by the Free Software Foundation; either
	  version 2 of the License, or (at your option) any later version.
 
	  This library is distributed in the hope that it will be useful,
	  but WITHOUT ANY WARRANTY; without even the implied warranty of
	  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
	  Library General Public License for more details.
 
	  You should have received a copy of the GNU Library General Public
	  License along with this library; if not, write to the Free
	  Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
=============================================================================*/

#include "image.h"
#include <stdio.h>

/*!
 */
namespace PLib {

/*!
  \brief draws a line from point 1 to point 2

  \latexonly
   Draws a line without aliasing from point $(i_1,j_1)$ to 
   $(i_2,j_2)$ with the value {\tt color}.
  \endlatexonly
  \htmlonly
   Draws a line without aliasing from point \a (i1,j1) to 
   \a (i2,j2) with the value \a color.  
  \endhtmlonly

  \param i1  the row of point 1
  \param j1  the column of point 1
  \param i2  the row of point 2
  \param j2  the column of point 2
  \param color  the line is drawn with this value

  \author Philippe Lavoie 
  \date 24 January 1997
*/
template <class T>
void MatrixImage<T>::drawLine(int i1, int j1, int i2, int j2, T color){
  int i,j ;
  double mx,b ;
  if(i1<0 || j1<0 || i1>rows() || j1>=cols()  ){
#ifdef USE_EXCEPTION
    throw OutOfBound2D(i1,j1,0,rows()-1,0,cols()-1) ;
#else
    Error error("MatrixImage<T>::drawLine") ;
    error << "Error in drawing line\n Invalid index ("<< i1 << ", " << j1 << ") to ( " << i2 << ", " << j2 << ") \n" ;
    error.warning() ;
#endif
    return ;
  }
  if(i2 <0 || j2<0 || i2>rows() || j2>=cols() ){
#ifdef USE_EXCEPTION
    throw OutOfBound2D(i2,j2,0,rows()-1,0,cols()-1) ;
#else
    Error error("MatrixImage<T>::drawLine") ;
    error << "Error in drawing line\n Invalid index ("<< i1 << ", " << j1 << ") to ( " << i2 << ", " << j2 << ") \n" ;
    error.warning() ;
#endif
    return ;
  }

  // check if line is vertical
  if(j1==j2){
    for(i=minimum(i1,i2);i<=maximum(i1,i2);i++)
     operator()(i,j1) = color ;
    return ;
  }
  mx = (double)(i1-i2)/(double)(j1-j2) ;
  b = (double)i1 - mx*j1 ;
  if(absolute(i1-i2)>absolute(j1-j2)){ // draw vertically
    if(i1>i2){
      for(i=i1;i>=i2;i--){
	j = int(((double)i-b)/mx) ;
	operator()(i,j) = color ;
      }
    }
    else{
      for(i=i1;i<=i2;i++){
	j = (int)((i-b)/mx) ;
	operator()(i,j) = color ;
      }
    }
  }
  else{
    if(j1>j2){
      for(j=j1;j>=j2;j--){
	i = (int)(mx*j+b) ;
	operator()(i,j) = color ;
      }
    }
    else{
      for(j=j1;j<=j2;j++){
	i = (int)(mx*j+b) ;
	operator()(i,j) = color ;
      }
    }
  }

}

/*!
  \brief draws a point of radius \a r

  Draws a point of radius \a r at location \a (i,j) with the 
  value \a color.

  \param i  the row of the center point to draw
  \param j  the column of the center point to draw
  \param r  the radius of the point
  \param color  the value to draw the point with

  \author Philippe Lavoie 
  \date 24 January 1997
*/
template <class T>
void MatrixImage<T>::drawPoint(int i, int j, double r , T color){
  for(int y=i-int(ceil(r)) ; y<i+int(ceil(r)) ; y++)
    for(int x = j-int(ceil(r)) ; x<j+int(ceil(r)) ; x++){
      if(y>=0 && y<rows() && x>=0 && x<cols()){
	if( ((y-i)*(y-i)+(x-j)*(x-j))<= r*r)
	  operator()(y,x) = color ;
      }
    }
}


/*!
  \brief copies an image to a Matrix

  copies the image to a matrix of the same type.

  \param a  the matrix to store the image to

  \author Philippe Lavoie 
  \date 24 January 1997
*/
template <class T>
void MatrixImage<T>::store(Matrix<T>& a){
  if(a.rows() != rows() || a.cols() != cols()) {
    a.resize(rows(),cols()) ;
  }
  T *aptr, *bptr ;
  int size,i ;
  aptr = &a(0,0)-1 ;
  bptr = m-1 ;
  size = cols()*rows() ;
  for(i=0;i<size;i++)
    *(++aptr) = *(++bptr) ;  
}

#ifdef WITH_IMAGE_MAGICK

/*!
  \brief default constructor

  \warning The IM_ImageT class must be of type \a Color or type 
               \a unsigned \a char.

  \author Philippe Lavoie 
  \date 24 January 1997
*/
template <class T>
IM_ImageT<T>::IM_ImageT(): MatrixImage<T>(){
  autoSave = 0 ;
  file_name = 0 ;
  image = 0 ;
  GetImageInfo(&image_info) ;
}

/*!
  \brief constructor with a filename and a save flag

  The image in \a filename will be read. If the save flag is 
  set to 1, then when the destructor is called the image is 
  saved to \a filename.

  If en error occurs, it is not reported. The use of the read 
  and write member functions is recommended instead of this 
  constructor.

  \param filename  the file to read an image from
  \param save  a flag indicating if autosave should occur, defaults to 0

  \warning The IM_ImageT class must be of type \a Color or type 
               unsigned char. The image stored in \a filename must 
	       be readable from the Image Magick library.

  \author Philippe Lavoie 
  \date 24 January 1997
*/
template <class T>
IM_ImageT<T>::IM_ImageT(const char* filename, int save): MatrixImage<T>(){
  autoSave = save ;
  file_name = new char[1024] ; // 1024 characters for the name of a file, should be enough
  (void)strcpy(file_name,filename) ;
  GetImageInfo(&image_info) ;
  read(filename) ;
}

/*!
  \brief constructor specifying the size of the image

  \param r  the number of rows() for the image
  \param c  the number of columns for the image

  \warning The IM_ImageT class must be of type \a Color or type 
           unsigned char.

  \author Philippe Lavoie 
  \date 24 January 1997
*/
template <class T>
IM_ImageT<T>::IM_ImageT(const int r, const int c): MatrixImage<T>(r,c){
  autoSave = 0 ;
  file_name = 0 ;
  image = 0 ;
  GetImageInfo(&image_info) ;
}

/*!
  \brief reads from a file an image

  Reads an image file. The filename should be in the format 
  ``imagename.type'' or ``type:imagename''.

  \param filename  the name of the file to read

  \warning The IM_ImageT class must be of type \a Color or type 
           unsigned char. The image stored in \a filename must 
	   be readable from the Image Magick library.

  \author Philippe Lavoie 
  \date 24 January 1997
*/
template <class T>
int IM_ImageT<T>::read(const char* filename) {
#ifdef USE_EXCEPTION
  throw MatrixErr() ;
#else
  Error error("IM_ImageT<T>::read") ;
  error << "An image of this type is NOT supported!\n" ;
  error.fatal() ;
#endif
  return 0;
}

/*!
  \brief writes to a file an image

  Writes to a file an image. The filename should be in the 
  format "imagename.type" or "type:imagename".

  \param filename  the file to write to. 

  \warning The \verb.IM_ImageT. class must be of type \a Color or type 
           unsigned char. \a filename must specify a valid type 
	   for the Image Magick library.

  \author Philippe Lavoie 
  \date 24 January 1997
*/
template <class T>
int IM_ImageT<T>::write(const char* filename) {
#ifdef USE_EXCEPTION
  throw MatrixErr() ;
#else
  Error error("IM_ImageT<T>::write") ;
  error << "An image of this type is NOT supported!\n" ;
  error.fatal() ;
#endif
  return 0 ;
}

/*!
  \brief sets the matrix internal data from the image data

  The matrix data is set to the one from the image data.
  This step is necessary since the ImageMagick data format 
  can't be made compatible with the matrix data format. The data 
  between the two internal formats must be copied each time 
  because of this.

  \param filename  the file to write to. 

  \warning The image data must be initialized properly.

  \author Philippe Lavoie 
  \date 24 January 1997
*/
template <class T>
void IM_ImageT<T>::setMatrix(){
#ifdef USE_EXCEPTION
  throw MatrixErr() ;
#else
  Error error("IM_ImageT<T>::setImage") ;
  error << "An image of this type is NOT supported!\n" ;
  error.fatal() ;
#endif
}


/*!
  \brief sets the image data from the matrix data.

  Sets the image data from the matrix data. This step is necessary
  since the ImageMagick data format can't be made compatible with
  the matrix data format. The data between the two internal 
  formats must be copied each time because of this.

  \param filename  the file to write to. 

  \warning image must be initialized.

  \author Philippe Lavoie 
  \date 24 January 1997
*/
template <class T>
void IM_ImageT<T>::setImage(){
#ifdef USE_EXCEPTION
  throw MatrixErr() ;
#else
  Error error("IM_ImageT<T>::setImage") ;
  error << "An image of this type is NOT supported!\n" ;
  error.fatal() ;
#endif
}

/*!
  \brief destructor

  If the autosave flag has been set, it saves the image to a file.

  \warning

  \author Philippe Lavoie 
  \date 24 January 1997
*/
template <class T>
IM_ImageT<T>::~IM_ImageT(){
  if(autoSave && file_name)
    write(file_name) ;
  if(image)
    DestroyImage(image) ;

  DestroyImageInfo(&image_info) ;
  if(file_name){
    delete []file_name ;
  }
}

#endif


} // end namespace