/src/dng_sdk/source/dng_image.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | /*****************************************************************************/ |
2 | | // Copyright 2006-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_image.cpp#1 $ */ |
10 | | /* $DateTime: 2012/05/30 13:28:51 $ */ |
11 | | /* $Change: 832332 $ */ |
12 | | /* $Author: tknoll $ */ |
13 | | |
14 | | /*****************************************************************************/ |
15 | | |
16 | | #include "dng_image.h" |
17 | | |
18 | | #include "dng_assertions.h" |
19 | | #include "dng_exceptions.h" |
20 | | #include "dng_orientation.h" |
21 | | #include "dng_pixel_buffer.h" |
22 | | #include "dng_tag_types.h" |
23 | | #include "dng_tile_iterator.h" |
24 | | #include "dng_utils.h" |
25 | | |
26 | | /*****************************************************************************/ |
27 | | |
28 | | dng_tile_buffer::dng_tile_buffer (const dng_image &image, |
29 | | const dng_rect &tile, |
30 | | bool dirty) |
31 | | |
32 | 2.01M | : fImage (image) |
33 | | , fRefData (NULL) |
34 | | |
35 | 2.01M | { |
36 | | |
37 | 2.01M | fImage.AcquireTileBuffer (*this, |
38 | 2.01M | tile, |
39 | 2.01M | dirty); |
40 | | |
41 | 2.01M | } |
42 | | |
43 | | /*****************************************************************************/ |
44 | | |
45 | | dng_tile_buffer::~dng_tile_buffer () |
46 | 2.01M | { |
47 | | |
48 | 2.01M | fImage.ReleaseTileBuffer (*this); |
49 | | |
50 | 2.01M | } |
51 | | |
52 | | /*****************************************************************************/ |
53 | | |
54 | | dng_const_tile_buffer::dng_const_tile_buffer (const dng_image &image, |
55 | | const dng_rect &tile) |
56 | | |
57 | 1.79M | : dng_tile_buffer (image, tile, false) |
58 | | |
59 | 1.79M | { |
60 | | |
61 | 1.79M | } |
62 | | |
63 | | /*****************************************************************************/ |
64 | | |
65 | | dng_const_tile_buffer::~dng_const_tile_buffer () |
66 | | { |
67 | | |
68 | | } |
69 | | |
70 | | /*****************************************************************************/ |
71 | | |
72 | | dng_dirty_tile_buffer::dng_dirty_tile_buffer (dng_image &image, |
73 | | const dng_rect &tile) |
74 | | |
75 | 218k | : dng_tile_buffer (image, tile, true) |
76 | | |
77 | 218k | { |
78 | | |
79 | 218k | } |
80 | | |
81 | | /*****************************************************************************/ |
82 | | |
83 | | dng_dirty_tile_buffer::~dng_dirty_tile_buffer () |
84 | | { |
85 | | |
86 | | } |
87 | | |
88 | | /*****************************************************************************/ |
89 | | |
90 | | dng_image::dng_image (const dng_rect &bounds, |
91 | | uint32 planes, |
92 | | uint32 pixelType) |
93 | | |
94 | 59.5k | : fBounds (bounds) |
95 | 59.5k | , fPlanes (planes) |
96 | 59.5k | , fPixelType (pixelType) |
97 | | |
98 | 59.5k | { |
99 | | |
100 | 59.5k | if (bounds.IsEmpty () || planes == 0 || PixelSize () == 0) |
101 | 252 | { |
102 | | |
103 | | #if qDNGValidate |
104 | | |
105 | | ReportError ("Fuzz: Attempt to create zero size image"); |
106 | | |
107 | | #endif |
108 | | |
109 | 252 | ThrowBadFormat (); |
110 | | |
111 | 252 | } |
112 | | |
113 | 59.5k | } |
114 | | |
115 | | /*****************************************************************************/ |
116 | | |
117 | | dng_image::~dng_image () |
118 | 59.2k | { |
119 | | |
120 | 59.2k | } |
121 | | |
122 | | /*****************************************************************************/ |
123 | | |
124 | | dng_image * dng_image::Clone () const |
125 | 0 | { |
126 | | |
127 | 0 | ThrowProgramError ("Clone is not supported by this dng_image subclass"); |
128 | |
|
129 | 0 | return NULL; |
130 | | |
131 | 0 | } |
132 | | |
133 | | /*****************************************************************************/ |
134 | | |
135 | | void dng_image::SetPixelType (uint32 pixelType) |
136 | 0 | { |
137 | | |
138 | 0 | if (TagTypeSize (pixelType) != PixelSize ()) |
139 | 0 | { |
140 | | |
141 | 0 | ThrowProgramError ("Cannot change pixel size for existing image"); |
142 | | |
143 | 0 | } |
144 | | |
145 | 0 | fPixelType = pixelType; |
146 | | |
147 | 0 | } |
148 | | |
149 | | /*****************************************************************************/ |
150 | | |
151 | | uint32 dng_image::PixelSize () const |
152 | 64.8k | { |
153 | | |
154 | 64.8k | return TagTypeSize (PixelType ()); |
155 | | |
156 | 64.8k | } |
157 | | |
158 | | /*****************************************************************************/ |
159 | | |
160 | | uint32 dng_image::PixelRange () const |
161 | 10.8k | { |
162 | | |
163 | 10.8k | switch (fPixelType) |
164 | 10.8k | { |
165 | | |
166 | 0 | case ttByte: |
167 | 0 | case ttSByte: |
168 | 0 | { |
169 | 0 | return 0x0FF; |
170 | 0 | } |
171 | | |
172 | 10.8k | case ttShort: |
173 | 10.8k | case ttSShort: |
174 | 10.8k | { |
175 | 10.8k | return 0x0FFFF; |
176 | 10.8k | } |
177 | | |
178 | 0 | case ttLong: |
179 | 0 | case ttSLong: |
180 | 0 | { |
181 | 0 | return 0xFFFFFFFF; |
182 | 0 | } |
183 | | |
184 | 0 | default: |
185 | 0 | break; |
186 | | |
187 | 10.8k | } |
188 | | |
189 | 0 | return 0; |
190 | | |
191 | 10.8k | } |
192 | | |
193 | | /*****************************************************************************/ |
194 | | |
195 | | dng_rect dng_image::RepeatingTile () const |
196 | 1.88M | { |
197 | | |
198 | 1.88M | return fBounds; |
199 | | |
200 | 1.88M | } |
201 | | |
202 | | /*****************************************************************************/ |
203 | | |
204 | | void dng_image::AcquireTileBuffer (dng_tile_buffer & /* buffer */, |
205 | | const dng_rect & /* area */, |
206 | | bool /* dirty */) const |
207 | 0 | { |
208 | | |
209 | 0 | ThrowProgramError (); |
210 | | |
211 | 0 | } |
212 | | |
213 | | /*****************************************************************************/ |
214 | | |
215 | | void dng_image::ReleaseTileBuffer (dng_tile_buffer & /* buffer */) const |
216 | 2.01M | { |
217 | | |
218 | 2.01M | } |
219 | | |
220 | | /*****************************************************************************/ |
221 | | |
222 | | void dng_image::DoGet (dng_pixel_buffer &buffer) const |
223 | 1.68M | { |
224 | | |
225 | 1.68M | dng_rect tile; |
226 | | |
227 | 1.68M | dng_tile_iterator iter (*this, buffer.fArea); |
228 | | |
229 | 3.37M | while (iter.GetOneTile (tile)) |
230 | 1.68M | { |
231 | | |
232 | 1.68M | dng_const_tile_buffer tileBuffer (*this, tile); |
233 | | |
234 | 1.68M | buffer.CopyArea (tileBuffer, |
235 | 1.68M | tile, |
236 | 1.68M | buffer.fPlane, |
237 | 1.68M | buffer.fPlanes); |
238 | | |
239 | 1.68M | } |
240 | | |
241 | 1.68M | } |
242 | | |
243 | | /*****************************************************************************/ |
244 | | |
245 | | void dng_image::DoPut (const dng_pixel_buffer &buffer) |
246 | 115k | { |
247 | | |
248 | 115k | dng_rect tile; |
249 | | |
250 | 115k | dng_tile_iterator iter (*this, buffer.fArea); |
251 | | |
252 | 231k | while (iter.GetOneTile (tile)) |
253 | 115k | { |
254 | | |
255 | 115k | dng_dirty_tile_buffer tileBuffer (*this, tile); |
256 | | |
257 | 115k | tileBuffer.CopyArea (buffer, |
258 | 115k | tile, |
259 | 115k | buffer.fPlane, |
260 | 115k | buffer.fPlanes); |
261 | | |
262 | 115k | } |
263 | | |
264 | 115k | } |
265 | | |
266 | | /*****************************************************************************/ |
267 | | |
268 | | void dng_image::GetRepeat (dng_pixel_buffer &buffer, |
269 | | const dng_rect &srcArea, |
270 | | const dng_rect &dstArea) const |
271 | 68.6k | { |
272 | | |
273 | | // If we already have the entire srcArea in the |
274 | | // buffer, we can just repeat that. |
275 | | |
276 | 68.6k | if ((srcArea & buffer.fArea) == srcArea) |
277 | 68.6k | { |
278 | | |
279 | 68.6k | buffer.RepeatArea (srcArea, |
280 | 68.6k | dstArea); |
281 | | |
282 | 68.6k | } |
283 | | |
284 | | // Else we first need to get the srcArea into the buffer area. |
285 | | |
286 | 0 | else |
287 | 0 | { |
288 | | |
289 | | // Find repeating pattern size. |
290 | | |
291 | 0 | dng_point repeat = srcArea.Size (); |
292 | | |
293 | | // Find pattern phase at top-left corner of destination area. |
294 | | |
295 | 0 | dng_point phase = dng_pixel_buffer::RepeatPhase (srcArea, |
296 | 0 | dstArea); |
297 | | |
298 | | // Find new source area at top-left of dstArea. |
299 | | |
300 | 0 | dng_rect newArea = srcArea + (dstArea.TL () - |
301 | 0 | srcArea.TL ()); |
302 | | |
303 | | // Find quadrant split coordinates. |
304 | | |
305 | 0 | int32 splitV = newArea.t + repeat.v - phase.v; |
306 | 0 | int32 splitH = newArea.l + repeat.h - phase.h; |
307 | | |
308 | | // Top-left quadrant. |
309 | | |
310 | 0 | dng_rect dst1 (dng_rect (newArea.t, |
311 | 0 | newArea.l, |
312 | 0 | splitV, |
313 | 0 | splitH) & dstArea); |
314 | | |
315 | 0 | if (dst1.NotEmpty ()) |
316 | 0 | { |
317 | | |
318 | 0 | dng_pixel_buffer temp (buffer); |
319 | | |
320 | 0 | temp.fArea = dst1 + (srcArea.TL () - |
321 | 0 | dstArea.TL () + |
322 | 0 | dng_point (phase.v, phase.h)); |
323 | | |
324 | 0 | temp.fData = buffer.DirtyPixel (dst1.t, |
325 | 0 | dst1.l, |
326 | 0 | buffer.fPlane); |
327 | | |
328 | 0 | DoGet (temp); |
329 | | |
330 | 0 | } |
331 | | |
332 | | // Top-right quadrant. |
333 | | |
334 | 0 | dng_rect dst2 (dng_rect (newArea.t, |
335 | 0 | splitH, |
336 | 0 | splitV, |
337 | 0 | newArea.r) & dstArea); |
338 | | |
339 | 0 | if (dst2.NotEmpty ()) |
340 | 0 | { |
341 | | |
342 | 0 | dng_pixel_buffer temp (buffer); |
343 | | |
344 | 0 | temp.fArea = dst2 + (srcArea.TL () - |
345 | 0 | dstArea.TL () + |
346 | 0 | dng_point (phase.v, -phase.h)); |
347 | | |
348 | 0 | temp.fData = buffer.DirtyPixel (dst2.t, |
349 | 0 | dst2.l, |
350 | 0 | buffer.fPlane); |
351 | | |
352 | 0 | DoGet (temp); |
353 | | |
354 | 0 | } |
355 | | |
356 | | // Bottom-left quadrant. |
357 | | |
358 | 0 | dng_rect dst3 (dng_rect (splitV, |
359 | 0 | newArea.l, |
360 | 0 | newArea.b, |
361 | 0 | splitH) & dstArea); |
362 | | |
363 | 0 | if (dst3.NotEmpty ()) |
364 | 0 | { |
365 | | |
366 | 0 | dng_pixel_buffer temp (buffer); |
367 | | |
368 | 0 | temp.fArea = dst3 + (srcArea.TL () - |
369 | 0 | dstArea.TL () + |
370 | 0 | dng_point (-phase.v, phase.h)); |
371 | | |
372 | 0 | temp.fData = buffer.DirtyPixel (dst3.t, |
373 | 0 | dst3.l, |
374 | 0 | buffer.fPlane); |
375 | | |
376 | 0 | DoGet (temp); |
377 | | |
378 | 0 | } |
379 | | |
380 | | // Bottom-right quadrant. |
381 | | |
382 | 0 | dng_rect dst4 (dng_rect (splitV, |
383 | 0 | splitH, |
384 | 0 | newArea.b, |
385 | 0 | newArea.r) & dstArea); |
386 | | |
387 | 0 | if (dst4.NotEmpty ()) |
388 | 0 | { |
389 | | |
390 | 0 | dng_pixel_buffer temp (buffer); |
391 | | |
392 | 0 | temp.fArea = dst4 + (srcArea.TL () - |
393 | 0 | dstArea.TL () + |
394 | 0 | dng_point (-phase.v, -phase.h)); |
395 | | |
396 | 0 | temp.fData = buffer.DirtyPixel (dst4.t, |
397 | 0 | dst4.l, |
398 | 0 | buffer.fPlane); |
399 | | |
400 | 0 | DoGet (temp); |
401 | | |
402 | 0 | } |
403 | | |
404 | | // Replicate this new source area. |
405 | | |
406 | 0 | buffer.RepeatArea (newArea, |
407 | 0 | dstArea); |
408 | | |
409 | 0 | } |
410 | | |
411 | 68.6k | } |
412 | | |
413 | | /*****************************************************************************/ |
414 | | |
415 | | void dng_image::GetEdge (dng_pixel_buffer &buffer, |
416 | | edge_option edgeOption, |
417 | | const dng_rect &srcArea, |
418 | | const dng_rect &dstArea) const |
419 | 197k | { |
420 | | |
421 | 197k | switch (edgeOption) |
422 | 197k | { |
423 | | |
424 | 128k | case edge_zero: |
425 | 128k | { |
426 | | |
427 | 128k | buffer.SetZero (dstArea, |
428 | 128k | buffer.fPlane, |
429 | 128k | buffer.fPlanes); |
430 | | |
431 | 128k | break; |
432 | | |
433 | 0 | } |
434 | | |
435 | 68.6k | case edge_repeat: |
436 | 68.6k | { |
437 | | |
438 | 68.6k | GetRepeat (buffer, |
439 | 68.6k | srcArea, |
440 | 68.6k | dstArea); |
441 | | |
442 | 68.6k | break; |
443 | | |
444 | 0 | } |
445 | | |
446 | 0 | case edge_repeat_zero_last: |
447 | 0 | { |
448 | | |
449 | 0 | if (buffer.fPlanes > 1) |
450 | 0 | { |
451 | | |
452 | 0 | dng_pixel_buffer buffer1 (buffer); |
453 | | |
454 | 0 | buffer1.fPlanes--; |
455 | | |
456 | 0 | GetEdge (buffer1, |
457 | 0 | edge_repeat, |
458 | 0 | srcArea, |
459 | 0 | dstArea); |
460 | | |
461 | 0 | } |
462 | | |
463 | 0 | dng_pixel_buffer buffer2 (buffer); |
464 | | |
465 | 0 | buffer2.fPlane = buffer.fPlanes - 1; |
466 | 0 | buffer2.fPlanes = 1; |
467 | | |
468 | 0 | buffer2.fData = buffer.DirtyPixel (buffer2.fArea.t, |
469 | 0 | buffer2.fArea.l, |
470 | 0 | buffer2.fPlane); |
471 | | |
472 | 0 | GetEdge (buffer2, |
473 | 0 | edge_zero, |
474 | 0 | srcArea, |
475 | 0 | dstArea); |
476 | | |
477 | 0 | break; |
478 | | |
479 | 0 | } |
480 | | |
481 | 0 | default: |
482 | 0 | { |
483 | | |
484 | 0 | ThrowProgramError (); |
485 | | |
486 | 0 | } |
487 | | |
488 | 197k | } |
489 | | |
490 | 197k | } |
491 | | |
492 | | /*****************************************************************************/ |
493 | | |
494 | | void dng_image::Get (dng_pixel_buffer &buffer, |
495 | | edge_option edgeOption, |
496 | | uint32 repeatV, |
497 | | uint32 repeatH) const |
498 | 1.68M | { |
499 | | |
500 | | // Find the overlap with the image bounds. |
501 | | |
502 | 1.68M | dng_rect overlap = buffer.fArea & fBounds; |
503 | | |
504 | | // Move the overlapping pixels. |
505 | | |
506 | 1.68M | if (overlap.NotEmpty ()) |
507 | 1.68M | { |
508 | | |
509 | 1.68M | dng_pixel_buffer temp (buffer); |
510 | | |
511 | 1.68M | temp.fArea = overlap; |
512 | | |
513 | 1.68M | temp.fData = buffer.DirtyPixel (overlap.t, |
514 | 1.68M | overlap.l, |
515 | 1.68M | buffer.fPlane); |
516 | | |
517 | 1.68M | DoGet (temp); |
518 | | |
519 | 1.68M | } |
520 | | |
521 | | // See if we need to pad the edge values. |
522 | | |
523 | 1.68M | if ((edgeOption != edge_none) && (overlap != buffer.fArea)) |
524 | 129k | { |
525 | | |
526 | 129k | dng_rect areaT (buffer.fArea); |
527 | 129k | dng_rect areaL (buffer.fArea); |
528 | 129k | dng_rect areaB (buffer.fArea); |
529 | 129k | dng_rect areaR (buffer.fArea); |
530 | | |
531 | 129k | areaT.b = Min_int32 (areaT.b, fBounds.t); |
532 | 129k | areaL.r = Min_int32 (areaL.r, fBounds.l); |
533 | 129k | areaB.t = Max_int32 (areaB.t, fBounds.b); |
534 | 129k | areaR.l = Max_int32 (areaR.l, fBounds.r); |
535 | | |
536 | 129k | dng_rect areaH (buffer.fArea); |
537 | 129k | dng_rect areaV (buffer.fArea); |
538 | | |
539 | 129k | areaH.l = Max_int32 (areaH.l, fBounds.l); |
540 | 129k | areaH.r = Min_int32 (areaH.r, fBounds.r); |
541 | | |
542 | 129k | areaV.t = Max_int32 (areaV.t, fBounds.t); |
543 | 129k | areaV.b = Min_int32 (areaV.b, fBounds.b); |
544 | | |
545 | | // Top left. |
546 | | |
547 | 129k | dng_rect areaTL = areaT & areaL; |
548 | | |
549 | 129k | if (areaTL.NotEmpty ()) |
550 | 3.63k | { |
551 | | |
552 | 3.63k | GetEdge (buffer, |
553 | 3.63k | edgeOption, |
554 | 3.63k | dng_rect (fBounds.t, |
555 | 3.63k | fBounds.l, |
556 | 3.63k | fBounds.t + (int32)repeatV, |
557 | 3.63k | fBounds.l + (int32)repeatH), |
558 | 3.63k | areaTL); |
559 | | |
560 | 3.63k | } |
561 | | |
562 | | // Top middle. |
563 | | |
564 | 129k | dng_rect areaTM = areaT & areaH; |
565 | | |
566 | 129k | if (areaTM.NotEmpty ()) |
567 | 20.9k | { |
568 | | |
569 | 20.9k | GetEdge (buffer, |
570 | 20.9k | edgeOption, |
571 | 20.9k | dng_rect (fBounds.t, |
572 | 20.9k | areaTM.l, |
573 | 20.9k | fBounds.t + (int32)repeatV, |
574 | 20.9k | areaTM.r), |
575 | 20.9k | areaTM); |
576 | | |
577 | 20.9k | } |
578 | | |
579 | | // Top right. |
580 | | |
581 | 129k | dng_rect areaTR = areaT & areaR; |
582 | | |
583 | 129k | if (areaTR.NotEmpty ()) |
584 | 3.66k | { |
585 | | |
586 | 3.66k | GetEdge (buffer, |
587 | 3.66k | edgeOption, |
588 | 3.66k | dng_rect (fBounds.t, |
589 | 3.66k | fBounds.r - (int32)repeatH, |
590 | 3.66k | fBounds.t + (int32)repeatV, |
591 | 3.66k | fBounds.r), |
592 | 3.66k | areaTR); |
593 | | |
594 | 3.66k | } |
595 | | |
596 | | // Left middle. |
597 | | |
598 | 129k | dng_rect areaLM = areaL & areaV; |
599 | | |
600 | 129k | if (areaLM.NotEmpty ()) |
601 | 6.00k | { |
602 | | |
603 | 6.00k | GetEdge (buffer, |
604 | 6.00k | edgeOption, |
605 | 6.00k | dng_rect (areaLM.t, |
606 | 6.00k | fBounds.l, |
607 | 6.00k | areaLM.b, |
608 | 6.00k | fBounds.l + (int32)repeatH), |
609 | 6.00k | areaLM); |
610 | | |
611 | 6.00k | } |
612 | | |
613 | | // Right middle. |
614 | | |
615 | 129k | dng_rect areaRM = areaR & areaV; |
616 | | |
617 | 129k | if (areaRM.NotEmpty ()) |
618 | 27.4k | { |
619 | | |
620 | 27.4k | GetEdge (buffer, |
621 | 27.4k | edgeOption, |
622 | 27.4k | dng_rect (areaRM.t, |
623 | 27.4k | fBounds.r - (int32)repeatH, |
624 | 27.4k | areaRM.b, |
625 | 27.4k | fBounds.r), |
626 | 27.4k | areaRM); |
627 | | |
628 | 27.4k | } |
629 | | |
630 | | // Bottom left. |
631 | | |
632 | 129k | dng_rect areaBL = areaB & areaL; |
633 | | |
634 | 129k | if (areaBL.NotEmpty ()) |
635 | 3.63k | { |
636 | | |
637 | 3.63k | GetEdge (buffer, |
638 | 3.63k | edgeOption, |
639 | 3.63k | dng_rect (fBounds.b - (int32)repeatV, |
640 | 3.63k | fBounds.l, |
641 | 3.63k | fBounds.b, |
642 | 3.63k | fBounds.l + (int32)repeatH), |
643 | 3.63k | areaBL); |
644 | | |
645 | 3.63k | } |
646 | | |
647 | | // Bottom middle. |
648 | | |
649 | 129k | dng_rect areaBM = areaB & areaH; |
650 | | |
651 | 129k | if (areaBM.NotEmpty ()) |
652 | 116k | { |
653 | | |
654 | 116k | GetEdge (buffer, |
655 | 116k | edgeOption, |
656 | 116k | dng_rect (fBounds.b - (int32)repeatV, |
657 | 116k | areaBM.l, |
658 | 116k | fBounds.b, |
659 | 116k | areaBM.r), |
660 | 116k | areaBM); |
661 | | |
662 | 116k | } |
663 | | |
664 | | // Bottom right. |
665 | | |
666 | 129k | dng_rect areaBR = areaB & areaR; |
667 | | |
668 | 129k | if (areaBR.NotEmpty ()) |
669 | 15.1k | { |
670 | | |
671 | 15.1k | GetEdge (buffer, |
672 | 15.1k | edgeOption, |
673 | 15.1k | dng_rect (fBounds.b - (int32)repeatV, |
674 | 15.1k | fBounds.r - (int32)repeatH, |
675 | 15.1k | fBounds.b, |
676 | 15.1k | fBounds.r), |
677 | 15.1k | areaBR); |
678 | | |
679 | 15.1k | } |
680 | | |
681 | 129k | } |
682 | | |
683 | 1.68M | } |
684 | | |
685 | | /*****************************************************************************/ |
686 | | |
687 | | void dng_image::Put (const dng_pixel_buffer &buffer) |
688 | 117k | { |
689 | | |
690 | | // Move the overlapping pixels. |
691 | | |
692 | 117k | dng_rect overlap = buffer.fArea & fBounds; |
693 | | |
694 | 117k | if (overlap.NotEmpty ()) |
695 | 115k | { |
696 | | |
697 | 115k | dng_pixel_buffer temp (buffer); |
698 | | |
699 | 115k | temp.fArea = overlap; |
700 | | |
701 | 115k | temp.fData = (void *) buffer.ConstPixel (overlap.t, |
702 | 115k | overlap.l, |
703 | 115k | buffer.fPlane); |
704 | | |
705 | | // Move the overlapping planes. |
706 | | |
707 | 115k | if (temp.fPlane < Planes ()) |
708 | 115k | { |
709 | | |
710 | 115k | temp.fPlanes = Min_uint32 (temp.fPlanes, |
711 | 115k | Planes () - temp.fPlane); |
712 | | |
713 | 115k | DoPut (temp); |
714 | | |
715 | 115k | } |
716 | | |
717 | 115k | } |
718 | | |
719 | 117k | } |
720 | | |
721 | | /*****************************************************************************/ |
722 | | |
723 | | void dng_image::Trim (const dng_rect &r) |
724 | 0 | { |
725 | | |
726 | 0 | if (r != Bounds ()) |
727 | 0 | { |
728 | | |
729 | 0 | ThrowProgramError ("Trim is not support by this dng_image subclass"); |
730 | | |
731 | 0 | } |
732 | | |
733 | 0 | } |
734 | | |
735 | | /*****************************************************************************/ |
736 | | |
737 | | void dng_image::Rotate (const dng_orientation &orientation) |
738 | 0 | { |
739 | | |
740 | 0 | if (orientation != dng_orientation::Normal ()) |
741 | 0 | { |
742 | | |
743 | 0 | ThrowProgramError ("Rotate is not support by this dng_image subclass"); |
744 | | |
745 | 0 | } |
746 | | |
747 | 0 | } |
748 | | |
749 | | /*****************************************************************************/ |
750 | | |
751 | | void dng_image::CopyArea (const dng_image &src, |
752 | | const dng_rect &area, |
753 | | uint32 srcPlane, |
754 | | uint32 dstPlane, |
755 | | uint32 planes) |
756 | 0 | { |
757 | |
|
758 | 0 | if (&src == this) |
759 | 0 | return; |
760 | | |
761 | 0 | dng_tile_iterator destIter(*this, area); |
762 | 0 | dng_rect destTileArea; |
763 | |
|
764 | 0 | while (destIter.GetOneTile(destTileArea)) |
765 | 0 | { |
766 | 0 | dng_tile_iterator srcIter(src, destTileArea); |
767 | 0 | dng_rect srcTileArea; |
768 | |
|
769 | 0 | while (srcIter.GetOneTile(srcTileArea)) |
770 | 0 | { |
771 | |
|
772 | 0 | dng_dirty_tile_buffer destTile(*this, srcTileArea); |
773 | 0 | dng_const_tile_buffer srcTile(src, srcTileArea); |
774 | |
|
775 | 0 | destTile.CopyArea (srcTile, srcTileArea, srcPlane, dstPlane, planes); |
776 | |
|
777 | 0 | } |
778 | |
|
779 | 0 | } |
780 | |
|
781 | 0 | } |
782 | | |
783 | | /*****************************************************************************/ |
784 | | |
785 | | bool dng_image::EqualArea (const dng_image &src, |
786 | | const dng_rect &area, |
787 | | uint32 plane, |
788 | | uint32 planes) const |
789 | 0 | { |
790 | |
|
791 | 0 | if (&src == this) |
792 | 0 | return true; |
793 | | |
794 | 0 | dng_tile_iterator destIter (*this, area); |
795 | | |
796 | 0 | dng_rect destTileArea; |
797 | |
|
798 | 0 | while (destIter.GetOneTile (destTileArea)) |
799 | 0 | { |
800 | | |
801 | 0 | dng_tile_iterator srcIter (src, destTileArea); |
802 | | |
803 | 0 | dng_rect srcTileArea; |
804 | |
|
805 | 0 | while (srcIter.GetOneTile (srcTileArea)) |
806 | 0 | { |
807 | |
|
808 | 0 | dng_const_tile_buffer destTile (*this, srcTileArea); |
809 | 0 | dng_const_tile_buffer srcTile (src , srcTileArea); |
810 | |
|
811 | 0 | if (!destTile.EqualArea (srcTile, srcTileArea, plane, planes)) |
812 | 0 | { |
813 | 0 | return false; |
814 | 0 | } |
815 | |
|
816 | 0 | } |
817 | |
|
818 | 0 | } |
819 | | |
820 | 0 | return true; |
821 | |
|
822 | 0 | } |
823 | | |
824 | | /*****************************************************************************/ |
825 | | |
826 | | void dng_image::SetConstant (uint32 value, |
827 | | const dng_rect &area) |
828 | 0 | { |
829 | | |
830 | 0 | dng_tile_iterator iter (*this, area); |
831 | | |
832 | 0 | dng_rect tileArea; |
833 | | |
834 | 0 | while (iter.GetOneTile (tileArea)) |
835 | 0 | { |
836 | | |
837 | 0 | dng_dirty_tile_buffer buffer (*this, tileArea); |
838 | | |
839 | 0 | buffer.SetConstant (tileArea, |
840 | 0 | 0, |
841 | 0 | fPlanes, |
842 | 0 | value); |
843 | | |
844 | 0 | } |
845 | |
|
846 | 0 | } |
847 | | |
848 | | /*****************************************************************************/ |