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