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 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406
|
//
// Lynkeos
// $Id$
//
// Created by Jean-Etienne LAMIAUD on Fri Mar 07 2005.
// Copyright (c) 2005-2023. Jean-Etienne LAMIAUD
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program 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 General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
/*!
* @header
* @abstract Definitions for the application image buffer class.
*/
#ifndef __LynkeosImageBuffer_H
#define __LynkeosImageBuffer_H
#import <Foundation/Foundation.h>
#include <LynkeosCore/LynkeosProcessing.h>
#define RED_PLANE 0 //!< Index of the red plane in RGB buffers
#define GREEN_PLANE 1 //!< Index of the green plane in RGB buffers
#define BLUE_PLANE 2 //!< Index of the blue plane in RGB buffers
/*!
* @abstract Internal type used for arithmetic operators.
* @discussion Either an image or a scalar.
* @ingroup Processing
*/
typedef union
{
LynkeosImageBuffer *term; //!< When operator acts on an image
float fscalar; //!< When operator acts on a single precision scalar
double dscalar; //!< When operator acts on a double precision scalar
} ArithmeticOperand_t;
/*!
* @abstract Internal method pointer to arithmetically process one line
*/
typedef void(*ImageProcessOneLine_t)(LynkeosImageBuffer*,
ArithmeticOperand_t*,
LynkeosImageBuffer*,
u_short);
//!< Internal type (used to locate either a standard or vectorized implementation)
typedef struct ArithmeticOperation
{
ImageProcessOneLine_t stdProcessOneLine;
ImageProcessOneLine_t vectProcessOneLine;
BOOL scalar; //!< Scalar operations have no second image argument
} ArithmeticOperation_t;
/*!
* @abstract Class used for floating precision images.
* @discussion For optimization purposes, the methods for accessing pixels
* value are implemented as macros
* @ingroup Processing
*/
@interface LynkeosImageBuffer : NSObject <NSCopying, LynkeosProcessingParameter>
{
@public
u_short _nPlanes; ///< Number of color planes
u_short _w; ///< Image pixels width
u_short _h; ///< Image pixels width
u_short _padw; ///< Padded line width (>= width)
u_short _padh; ///< Padded image height (>= height)
void *_data; ///< Pixel buffer, the planes are consecutive
@protected
REAL *_planes[3]; ///< Shortcuts to the color planes
BOOL _freeWhenDone; ///< Whether to free the planes on dealloc
double _min[4]; ///< The image minimum value
double _max[4]; ///< The image maximum value
double _mean[4]; ///< The image mean
//! Is vectorization usable, or not
BOOL _vectorsAllowed;
//! Strategy method for processing an image, actually for debug
SEL _process_image_selector;
//! Strategy method for processing an image, func pointer which is called
void (*_process_image)(id,SEL,ArithmeticOperand_t*,
LynkeosImageBuffer*,
const ArithmeticOperation_t*);
}
/*!
* @abstract Allocates a new empty buffer
* @param nPlanes Number of color planes for this image
* @param w Image pixels width
* @param h Image pixels height
* @result The initialized buffer.
*/
- (id) initWithNumberOfPlanes:(u_short)nPlanes
width:(u_short)w height:(u_short)h ;
/*!
* @abstract Initialize a new buffer with preexisting data
* @param data Image data
* @param copy Whether to copy the data
* @param freeWhenDone Whether to free the planes on dealloc (relevant only when
* copy is NO)
* @param nPlanes Number of color planes for this image
* @param w Image pixels width
* @param padw Padded width of the data
* @param h Image pixels height
* @result The initialized buffer.
*/
- (id) initWithData:(void*)data
copy:(BOOL)copy freeWhenDone:(BOOL)freeWhenDone
numberOfPlanes:(u_short)nPlanes
width:(u_short)w paddedWidth:(u_short)padw height:(u_short)h ;
/*!
* @abstract Initialize a sub-image from an existing image
* @discussion Create a sub-image referencing the data of the full-size image. The given frame shall
* be entirely contained in the full-size image
* @param image Full-size image
* @param x Sub-image x origin
* @param y Sub-image y origin
* @param w Sub-image pixels width
* @param h Sub-image pixels height
* @result The LynkeosImageBuffer sub-image
*/
- (id) initSubImageBufferWithImage:(LynkeosImageBuffer*)image
x:(u_short)x y:(u_short)y
width:(u_short)w height:(u_short)h ;
/*!
* @abstract The memory size occupied by this item
* @discussion The object shall use class_getInstanceSize and add the size of
* any aggregated objects and "mallocated" buffers.
* @result The item's size
*/
- (size_t) memorySize ;
/*!
* @abstract Get the image pixels width
* @result The image width
*/
- (u_short) width ;
/*!
* @abstract Get the image pixels height
* @result The image height
*/
- (u_short) height ;
/*!
* @abstract Get the number of color planes
* @result The number of color planes
*/
- (u_short) numberOfPlanes ;
/*!
* @abstract Retrieve a Cocoa 24 bits RGB bitmap representation
* @discussion The black, white and gamma are arrays of values for each plane,
* and a last "global" value that is applied equally on each plane.
* @param black Black level for conversion for each plane
* @param white White level for conversion for each plane
* @param gamma Gamma correction exponent for each plane (ie: 1 = no correction)
* @result The 8 bits RGB bitmap representation of the buffer data
*/
#if !GNUSTEP
- (CGImageRef) getImageInRect:(LynkeosIntegerRect)rect
withBlack:(double*)black white:(double*)white gamma:(double*)gamma;
#else
- (NSBitmapImageRep*) getNSImageWithBlack:(double*)black white:(double*)white
gamma:(double*)gamma;
#endif
/*!
* @abstract Change the strategy of processing
* @discussion The items are always created with the standard strategy (no parallelization).
* @param strategy The new strategy
*/
- (void) setOperatorsStrategy:(ImageOperatorsStrategy_t)strategy ;
/*!
* @abstract Add another image buffer.
* @discussion The image to add shall be an instance of the same class as self
* and have the same size (method implementation can rely on this).
* @param image The image to add
*/
- (void) add :(LynkeosImageBuffer*)image ;
/*!
* @abstract Calibrate the image with the calibration images.
* @discussion darkFrame and flatField, when present, are instances of the same
* class as self. They are "full sensor" images.
*
* The darkFrame, if any, shall be substracted from the image and the result
* shall be divided by the flatField, if any.
*
* The coordinates are specified using the same orientation as in
* LynkeosFileReader
* @param darkFrame The dark frame image, nil if not present
* @param flatField The flat field image, nil if not present
* @param ox The X origin of our image in the full sensor frame.
* @param oy The Y origin of our image in the full sensor frame.
*/
- (void) calibrateWithDarkFrame:(LynkeosImageBuffer*)darkFrame
flatField:(LynkeosImageBuffer*)flatField
atX:(u_short)ox Y:(u_short)oy ;
/*!
* @abstract Multiplies all values with a scalar
* @param factor The value by which each pixel is multiplied. If 0, the factor
* is taken as to set the maximum value of the resulting image to 1.0
* @param mono If true and factor is zero, the color planes are leveled to
* obtain a non color biased image
*/
- (void) normalizeWithFactor:(double)factor mono:(BOOL)mono ;
/*!
* @abstract Normalize the image to a maximum 1.0 level
*/
- (void) normalize ;
/*!
* @abstract Convert the image buffer data to a floating precision planar
* representation.
* @discussion The pixels ordering is the same as in LynkeosFileReader.
* @param planes The color planes to fill with the image data. There are as
* many planes as there are in this instance and their size is the same as
* this instance's image.
* @param nPlanes Number of planes in the output buffer.
* @param precision The floating precision of pixels in the output buffer.
* @param lineW The line width of the output buffer (may be larger than this
* instance's image width).
*/
- (void) convertToPlanar:(REAL * const * const)planes
withPlanes:(u_short)nPlanes
lineWidth:(u_short)lineW ;
/*!
* @abstract Clear the image contents ; all samples are zeroes
*/
- (void) clear ;
/*!
* @abstract Subclasses that use a different data format must return true
* @result Wether the image data is stored in a nonstandard format
*/
- (BOOL) hasCustomFormat;
/*!
* @abstract Reset the min and max to unset values
*/
- (void) resetMinMax ;
/*!
* @abstract Get the minimum and maximum pixels value
* @param[out] vmin Minimum pixel value
* @param[out] vmax Maximum pixel value
*/
- (void) getMinLevel:(double*)vmin maxLevel:(double*)vmax ;
/*!
* @abstract Get the minimum and maximum pixels value for a given plane
* @param[out] vmin Minimum pixel value
* @param[out] vmax Maximum pixel value
* @param plane he plane for which min and max will be returned
*/
- (void) getMinLevel:(double*)vmin maxLevel:(double*)vmax
forPlane:(u_short)plane;
/*!
* @abstract Get the mean pixel value
* @result Mean pixel value
*/
- (double) mean;
/*!
* @abstract Get the mean pixel value for a given plane
* @result Mean pixel value
*/
- (double) meanForPlane:(u_short)plane;
/*!
* @abstract Access to the color planes
* @result An array of pointer to the color planes
*/
- (REAL * const * const) colorPlanes ;
/*!
* @abstract Access to one color component of a pixel
* @discussion This method is implemented as a macro for speed purpose
* @param buf An instance of LynkeosImageBuffer
* @param x Pixel's x coordinate
* @param y Pixel's y coordinate
* @param c Color plane
* @result The access for this pixel (it can be used as an lvalue)
* @relates LynkeosImageBuffer
* @ingroup Processing
*/
#define stdColorValue(buf,x,y,c) \
(((REAL*)(buf)->_data)[((y)+(c)*(buf)->_padh)*(buf)->_padw+(x)])
/*!
* @abstract Extract a rectangle in the image
*/
- (void) extractSample:(REAL * const * const)planes
atX:(u_short)x Y:(u_short)y
withWidth:(u_short)w height:(u_short)h
withPlanes:(u_short)nPlanes
lineWidth:(u_short)lineW ;
/*!
* @abstract Substract an image from another
* @param image The other image to substract
*/
- (void) substract:(LynkeosImageBuffer*)image ;
/*!
* @abstract Multiplication
* @discussion Term shall either have the same number of planes as the receiver
* or only one plane. In the latter case, the plane is applied to each planes
* of the receiver.
* @param term other term
* @param result where the result is stored, can be one of the terms.
*/
- (void) multiplyWith:(LynkeosImageBuffer*)term
result:(LynkeosImageBuffer*)result ;
/*!
* @abstract Substract and multiply with scalars
* @param bias The bias to substract
* @param scale The scalar by which all pixels are multiplied
*/
- (void) substractBias:(double)bias andScale:(double)scale;
/*!
* @abstract Multiplication with a scalar
* @param scalar The scalar by wich all pixels are multiplied
*/
- (void) multiplyWithScalar:(double)scalar ;
/*!
* @abstract Division
* @discussion term shall either have the same number of planes as the receiver
* or only one plane. In the latter case, the plane is applied to each planes
* of the receiver.
* @param denom Denominator of the division
* @param result where the result is stored, can be one of the terms
*/
- (void) divideBy:(LynkeosImageBuffer*)denom
result:(LynkeosImageBuffer*)result ;
/*!
* @abstract Convenience empty image buffer creator
* @param nPlanes Number of color planes for this image
* @param w Image pixels width
* @param h Image pixels height
* @result The allocated and initialized LynkeosImageBuffer.
*/
+ (LynkeosImageBuffer*) imageBufferWithNumberOfPlanes:(u_short)nPlanes
width:(u_short)w height:(u_short)h ;
/*!
* @abstract Convenience initialized image buffer creator
* @param data Image data
* @param copy Wether to copy the data
* @param freeWhenDone Whether to free the planes on dealloc (relevant only when
* copy is NO)
* @param nPlanes Number of color planes for this image
* @param w Image pixels width
* @param padw Padded width of the data
* @param h Image pixels height
* @result The allocated and initialized LynkeosImageBuffer.
*/
+ (LynkeosImageBuffer*) imageBufferWithData:(void*)data
copy:(BOOL)copy freeWhenDone:(BOOL)freeWhenDone
numberOfPlanes:(u_short)nPlanes
width:(u_short)w paddedWidth:(u_short)padw
height:(u_short)h ;
/*!
* @abstract Convenience sub-image buffer creator
* @discussion Create a sub-image referencing the data of the full-size image. The given frame shall
* be entirely contained in the full-size image
* @param image Full-size image
* @param x Sub-image x origin
* @param y Sub-image y origin
* @param w Sub-image pixels width
* @param h Sub-image pixels height
* @result The LynkeosImageBuffer sub-image
*/
+ (LynkeosImageBuffer*) subImageBufferWithImage:(LynkeosImageBuffer*)image
x:(u_short)x y:(u_short)y
width:(u_short)w height:(u_short)h ;
@end
#endif
|