1 /*****************************************************************************/
2 // Copyright 2008 Adobe Systems Incorporated
3 // All Rights Reserved.
4 //
5 // NOTICE:  Adobe permits you to use, modify, and distribute this file in
6 // accordance with the terms of the Adobe license agreement accompanying it.
7 /*****************************************************************************/
8 
9 /* $Id: //mondo/dng_sdk_1_4/dng_sdk/source/dng_bad_pixels.h#3 $ */
10 /* $DateTime: 2012/07/11 10:36:56 $ */
11 /* $Change: 838485 $ */
12 /* $Author: tknoll $ */
13 
14 /** \file
15  * Opcodes to fix defective pixels, including individual pixels and regions (such as
16  * defective rows and columns).
17  */
18 
19 /*****************************************************************************/
20 
21 #ifndef __dng_bad_pixels__
22 #define __dng_bad_pixels__
23 
24 /*****************************************************************************/
25 
26 #include "dng_memory.h"
27 #include "dng_opcodes.h"
28 
29 #include <vector>
30 
31 /*****************************************************************************/
32 
33 /// \brief An opcode to fix individual bad pixels that are marked with a constant
34 /// value (e.g., 0) in a Bayer image.
35 
36 class dng_opcode_FixBadPixelsConstant: public dng_filter_opcode
37 	{
38 
39 	private:
40 
41 		uint32 fConstant;
42 
43 		uint32 fBayerPhase;
44 
45 	public:
46 
47 		/// Construct an opcode to fix an individual bad pixels that are marked with
48 		/// a constant value in a Bayer image.
49 		/// \param constant The constant value that indicates a bad pixel.
50 		/// \param bayerPhase The phase of the Bayer mosaic pattern (0, 1, 2, 3).
51 
52 		dng_opcode_FixBadPixelsConstant (uint32 constant,
53 										 uint32 bayerPhase);
54 
55 		dng_opcode_FixBadPixelsConstant (dng_stream &stream);
56 
57 		virtual void PutData (dng_stream &stream) const;
58 
59 		virtual dng_point SrcRepeat ();
60 
61 		virtual dng_rect SrcArea (const dng_rect &dstArea,
62 								  const dng_rect &imageBounds);
63 
64 		virtual void Prepare (dng_negative &negative,
65 							  uint32 threadCount,
66 							  const dng_point &tileSize,
67 							  const dng_rect &imageBounds,
68 							  uint32 imagePlanes,
69 							  uint32 bufferPixelType,
70 							  dng_memory_allocator &allocator);
71 
72 		virtual void ProcessArea (dng_negative &negative,
73 								  uint32 threadIndex,
74 								  dng_pixel_buffer &srcBuffer,
75 								  dng_pixel_buffer &dstBuffer,
76 								  const dng_rect &dstArea,
77 								  const dng_rect &imageBounds);
78 
79 	protected:
80 
81 #if defined(__clang__) && defined(__has_attribute)
82 #if __has_attribute(no_sanitize)
83 __attribute__((no_sanitize("unsigned-integer-overflow")))
84 #endif
85 #endif
IsGreen(int32 row,int32 col)86 		bool IsGreen (int32 row, int32 col) const
87 			{
88 			return (((uint32) row + (uint32) col + fBayerPhase + (fBayerPhase >> 1)) & 1) == 0;
89 			}
90 
91 	};
92 
93 /*****************************************************************************/
94 
95 /// \brief A list of bad pixels and rectangles (usually single rows or columns).
96 
97 class dng_bad_pixel_list
98 	{
99 
100 	public:
101 
102 		enum
103 			{
104 			kNoIndex = 0xFFFFFFFF
105 			};
106 
107 	private:
108 
109 		// List of bad single pixels.
110 
111 		dng_std_vector<dng_point> fBadPoints;
112 
113 		// List of bad rectangles (usually single rows or columns).
114 
115 		dng_std_vector<dng_rect> fBadRects;
116 
117 	public:
118 
119 		/// Create an empty bad pixel list.
120 
121 		dng_bad_pixel_list ();
122 
123 		/// Returns the number of bad single pixels.
124 
PointCount()125 		uint32 PointCount () const
126 			{
127 			return (uint32) fBadPoints.size ();
128 			}
129 
130 		/// Retrieves the bad single pixel coordinate via the specified list index.
131 		///
132 		/// \param index The list index from which to retrieve the bad single pixel
133 		/// coordinate.
134 
Point(uint32 index)135 		const dng_point & Point (uint32 index) const
136 			{
137 			return fBadPoints [index];
138 			}
139 
140 		/// Returns the number of bad rectangles.
141 
RectCount()142 		uint32 RectCount () const
143 			{
144 			return (uint32) fBadRects.size ();
145 			}
146 
147 		/// Retrieves the bad rectangle via the specified list index.
148 		///
149 		/// \param index The list index from which to retrieve the bad rectangle
150 		/// coordinates.
151 
Rect(uint32 index)152 		const dng_rect & Rect (uint32 index) const
153 			{
154 			return fBadRects [index];
155 			}
156 
157 		/// Returns true iff there are zero bad single pixels and zero bad
158 		/// rectangles.
159 
IsEmpty()160 		bool IsEmpty () const
161 			{
162 			return PointCount () == 0 &&
163 				   RectCount  () == 0;
164 			}
165 
166 		/// Returns true iff there is at least one bad single pixel or at least one
167 		/// bad rectangle.
168 
NotEmpty()169 		bool NotEmpty () const
170 			{
171 			return !IsEmpty ();
172 			}
173 
174 		/// Add the specified coordinate to the list of bad single pixels.
175 		///
176 		/// \param pt The bad single pixel to add.
177 
178 		void AddPoint (const dng_point &pt);
179 
180 		/// Add the specified rectangle to the list of bad rectangles.
181 		///
182 		/// \param pt The bad rectangle to add.
183 
184 		void AddRect (const dng_rect &r);
185 
186 		/// Sort the bad single pixels and bad rectangles by coordinates (top to
187 		/// bottom, then left to right).
188 
189 		void Sort ();
190 
191 		/// Returns true iff the specified bad single pixel is isolated, i.e., there
192 		/// is no other bad single pixel or bad rectangle that lies within radius
193 		/// pixels of this bad single pixel.
194 		///
195 		/// \param index The index of the bad single pixel to test.
196 		/// \param radius The pixel radius to test for isolation.
197 
198 		bool IsPointIsolated (uint32 index,
199 							  uint32 radius) const;
200 
201 		/// Returns true iff the specified bad rectangle is isolated, i.e., there
202 		/// is no other bad single pixel or bad rectangle that lies within radius
203 		/// pixels of this bad rectangle.
204 		///
205 		/// \param index The index of the bad rectangle to test.
206 		/// \param radius The pixel radius to test for isolation.
207 
208 		bool IsRectIsolated (uint32 index,
209 							 uint32 radius) const;
210 
211 		/// Returns true iff the specified point is valid, i.e., lies within the
212 		/// specified image bounds, is different from all other bad single pixels,
213 		/// and is not contained in any bad rectangle. The second and third
214 		/// conditions are only checked if provided with a starting search index.
215 		///
216 		/// \param pt The point to test for validity.
217 		/// \param imageBounds The pt must lie within imageBounds to be valid.
218 		/// \index The search index to use (or kNoIndex, to avoid a search) for
219 		/// checking for validity.
220 
221 		bool IsPointValid (const dng_point &pt,
222 						   const dng_rect &imageBounds,
223 						   uint32 index = kNoIndex) const;
224 
225 	};
226 
227 /*****************************************************************************/
228 
229 /// \brief An opcode to fix lists of bad pixels (indicated by position) in a Bayer
230 /// image.
231 
232 class dng_opcode_FixBadPixelsList: public dng_filter_opcode
233 	{
234 
235 	protected:
236 
237 		enum
238 			{
239 			kBadPointPadding = 2,
240 			kBadRectPadding  = 4
241 			};
242 
243 	private:
244 
245 		AutoPtr<dng_bad_pixel_list> fList;
246 
247 		uint32 fBayerPhase;
248 
249 	public:
250 
251 		/// Construct an opcode to fix lists of bad pixels (indicated by position) in
252 		/// a Bayer image.
253 		/// \param list The list of bad pixels to fix.
254 		/// \param bayerPhase The phase of the Bayer mosaic pattern (0, 1, 2, 3).
255 
256 		dng_opcode_FixBadPixelsList (AutoPtr<dng_bad_pixel_list> &list,
257 									 uint32 bayerPhase);
258 
259 		dng_opcode_FixBadPixelsList (dng_stream &stream);
260 
261 		virtual void PutData (dng_stream &stream) const;
262 
263 		virtual dng_point SrcRepeat ();
264 
265 		virtual dng_rect SrcArea (const dng_rect &dstArea,
266 								  const dng_rect &imageBounds);
267 
268 		virtual void Prepare (dng_negative &negative,
269 							  uint32 threadCount,
270 							  const dng_point &tileSize,
271 							  const dng_rect &imageBounds,
272 							  uint32 imagePlanes,
273 							  uint32 bufferPixelType,
274 							  dng_memory_allocator &allocator);
275 
276 		virtual void ProcessArea (dng_negative &negative,
277 								  uint32 threadIndex,
278 								  dng_pixel_buffer &srcBuffer,
279 								  dng_pixel_buffer &dstBuffer,
280 								  const dng_rect &dstArea,
281 								  const dng_rect &imageBounds);
282 
283 	protected:
284 
IsGreen(int32 row,int32 col)285 		bool IsGreen (int32 row, int32 col) const
286 			{
287 			return ((row + col + fBayerPhase + (fBayerPhase >> 1)) & 1) == 0;
288 			}
289 
290 		virtual void FixIsolatedPixel (dng_pixel_buffer &buffer,
291 									   dng_point &badPoint);
292 
293 		virtual void FixClusteredPixel (dng_pixel_buffer &buffer,
294 								        uint32 pointIndex,
295 										const dng_rect &imageBounds);
296 
297 		virtual void FixSingleColumn (dng_pixel_buffer &buffer,
298 									  const dng_rect &badRect);
299 
300 		virtual void FixSingleRow (dng_pixel_buffer &buffer,
301 								   const dng_rect &badRect);
302 
303 		virtual void FixClusteredRect (dng_pixel_buffer &buffer,
304 									   const dng_rect &badRect,
305 									   const dng_rect &imageBounds);
306 
307 	};
308 
309 /*****************************************************************************/
310 
311 #endif
312 
313 /*****************************************************************************/
314