Bug 1643246 - Don't use attribute selectors for determining if a select is a drop...
[gecko.git] / image / SurfacePipeFactory.h
blob4f816554b6ea9be64bb30dc700ac08be64028728
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #ifndef mozilla_image_SurfacePipeFactory_h
8 #define mozilla_image_SurfacePipeFactory_h
10 #include "SurfacePipe.h"
11 #include "SurfaceFilters.h"
13 namespace mozilla {
14 namespace image {
16 namespace detail {
18 /**
19 * FilterPipeline is a helper template for SurfacePipeFactory that determines
20 * the full type of the sequence of SurfaceFilters that a sequence of
21 * configuration structs corresponds to. To make this work, all configuration
22 * structs must include a typedef 'Filter' that identifies the SurfaceFilter
23 * they configure.
25 template <typename... Configs>
26 struct FilterPipeline;
28 template <typename Config, typename... Configs>
29 struct FilterPipeline<Config, Configs...> {
30 typedef typename Config::template Filter<
31 typename FilterPipeline<Configs...>::Type>
32 Type;
35 template <typename Config>
36 struct FilterPipeline<Config> {
37 typedef typename Config::Filter Type;
40 } // namespace detail
42 /**
43 * Flags for SurfacePipeFactory, used in conjunction with the factory functions
44 * in SurfacePipeFactory to enable or disable various SurfacePipe
45 * functionality.
47 enum class SurfacePipeFlags {
48 DEINTERLACE = 1 << 0, // If set, deinterlace the image.
50 ADAM7_INTERPOLATE =
51 1 << 1, // If set, the caller is deinterlacing the
52 // image using ADAM7, and we may want to
53 // interpolate it for better intermediate results.
55 FLIP_VERTICALLY = 1 << 2, // If set, flip the image vertically.
57 PROGRESSIVE_DISPLAY = 1 << 3, // If set, we expect the image to be displayed
58 // progressively. This enables features that
59 // result in a better user experience for
60 // progressive display but which may be more
61 // computationally expensive.
63 PREMULTIPLY_ALPHA = 1 << 4, // If set, we want to premultiply the alpha
64 // channel and the individual color channels.
66 MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(SurfacePipeFlags)
68 class SurfacePipeFactory {
69 public:
70 /**
71 * Creates and initializes a normal (i.e., non-paletted) SurfacePipe.
73 * @param aDecoder The decoder whose current frame the SurfacePipe will write
74 * to.
75 * @param aInputSize The original size of the image.
76 * @param aOutputSize The size the SurfacePipe should output. Must be the same
77 * as @aInputSize or smaller. If smaller, the image will be
78 * downscaled during decoding.
79 * @param aFrameRect The portion of the image that actually contains data.
80 * @param aFormat The surface format of the image; generally B8G8R8A8 or
81 * B8G8R8X8.
82 * @param aAnimParams Extra parameters used by animated images.
83 * @param aFlags Flags enabling or disabling various functionality for the
84 * SurfacePipe; see the SurfacePipeFlags documentation for more
85 * information.
87 * @return A SurfacePipe if the parameters allowed one to be created
88 * successfully, or Nothing() if the SurfacePipe could not be
89 * initialized.
91 static Maybe<SurfacePipe> CreateSurfacePipe(
92 Decoder* aDecoder, const nsIntSize& aInputSize,
93 const nsIntSize& aOutputSize, const nsIntRect& aFrameRect,
94 gfx::SurfaceFormat aInFormat, gfx::SurfaceFormat aOutFormat,
95 const Maybe<AnimationParams>& aAnimParams, qcms_transform* aTransform,
96 SurfacePipeFlags aFlags) {
97 const bool deinterlace = bool(aFlags & SurfacePipeFlags::DEINTERLACE);
98 const bool flipVertically =
99 bool(aFlags & SurfacePipeFlags::FLIP_VERTICALLY);
100 const bool progressiveDisplay =
101 bool(aFlags & SurfacePipeFlags::PROGRESSIVE_DISPLAY);
102 const bool downscale = aInputSize != aOutputSize;
103 const bool removeFrameRect = !aFrameRect.IsEqualEdges(
104 nsIntRect(0, 0, aInputSize.width, aInputSize.height));
105 const bool blendAnimation = aAnimParams.isSome();
106 const bool colorManagement = aTransform != nullptr;
107 const bool premultiplyAlpha =
108 bool(aFlags & SurfacePipeFlags::PREMULTIPLY_ALPHA);
110 MOZ_ASSERT(aInFormat == gfx::SurfaceFormat::R8G8B8 ||
111 aInFormat == gfx::SurfaceFormat::R8G8B8A8 ||
112 aInFormat == gfx::SurfaceFormat::R8G8B8X8 ||
113 aInFormat == gfx::SurfaceFormat::OS_RGBA ||
114 aInFormat == gfx::SurfaceFormat::OS_RGBX);
116 MOZ_ASSERT(aOutFormat == gfx::SurfaceFormat::OS_RGBA ||
117 aOutFormat == gfx::SurfaceFormat::OS_RGBX);
119 const bool inFormatRgb = aInFormat == gfx::SurfaceFormat::R8G8B8;
121 const bool inFormatOpaque = aInFormat == gfx::SurfaceFormat::OS_RGBX ||
122 aInFormat == gfx::SurfaceFormat::R8G8B8X8 ||
123 inFormatRgb;
124 const bool outFormatOpaque = aOutFormat == gfx::SurfaceFormat::OS_RGBX;
126 const bool inFormatOrder = aInFormat == gfx::SurfaceFormat::R8G8B8A8 ||
127 aInFormat == gfx::SurfaceFormat::R8G8B8X8;
128 const bool outFormatOrder = aOutFormat == gfx::SurfaceFormat::R8G8B8A8 ||
129 aOutFormat == gfx::SurfaceFormat::R8G8B8X8;
131 // Early swizzles are for unpacking RGB or forcing RGBA/BGRA_U32 to
132 // RGBX/BGRX_U32. We should never want to premultiply in either case,
133 // because the image's alpha channel will always be opaque. This must be
134 // done before downscaling and color management.
135 bool unpackOrMaskSwizzle =
136 inFormatRgb ||
137 (!inFormatOpaque && outFormatOpaque && inFormatOrder == outFormatOrder);
139 // Late swizzles are for premultiplying RGBA/BGRA_U32 and/or possible
140 // converting between RGBA and BGRA_U32. It must happen after color
141 // management, and before downscaling.
142 bool swapOrAlphaSwizzle =
143 (!inFormatRgb && inFormatOrder != outFormatOrder) || premultiplyAlpha;
145 if (unpackOrMaskSwizzle && swapOrAlphaSwizzle) {
146 MOZ_ASSERT_UNREACHABLE("Early and late swizzles not supported");
147 return Nothing();
150 if (!unpackOrMaskSwizzle && !swapOrAlphaSwizzle &&
151 aInFormat != aOutFormat) {
152 MOZ_ASSERT_UNREACHABLE("Need to swizzle, but not configured to");
153 return Nothing();
156 // Don't interpolate if we're sure we won't show this surface to the user
157 // until it's completely decoded. The final pass of an ADAM7 image doesn't
158 // need interpolation, so we only need to interpolate if we'll be displaying
159 // the image while it's still being decoded.
160 const bool adam7Interpolate =
161 bool(aFlags & SurfacePipeFlags::ADAM7_INTERPOLATE) &&
162 progressiveDisplay;
164 if (deinterlace && adam7Interpolate) {
165 MOZ_ASSERT_UNREACHABLE("ADAM7 deinterlacing is handled by libpng");
166 return Nothing();
169 // Construct configurations for the SurfaceFilters. Note that the order of
170 // these filters is significant. We want to deinterlace or interpolate raw
171 // input rows, before any other transformations, and we want to remove the
172 // frame rect (which may involve adding blank rows or columns to the image)
173 // before any downscaling, so that the new rows and columns are taken into
174 // account.
175 DeinterlacingConfig<uint32_t> deinterlacingConfig{progressiveDisplay};
176 ADAM7InterpolatingConfig interpolatingConfig;
177 RemoveFrameRectConfig removeFrameRectConfig{aFrameRect};
178 BlendAnimationConfig blendAnimationConfig{aDecoder};
179 DownscalingConfig downscalingConfig{aInputSize, aOutFormat};
180 ColorManagementConfig colorManagementConfig{aTransform};
181 SwizzleConfig swizzleConfig{aInFormat, aOutFormat, premultiplyAlpha};
182 SurfaceConfig surfaceConfig{aDecoder, aOutputSize, aOutFormat,
183 flipVertically, aAnimParams};
185 Maybe<SurfacePipe> pipe;
187 if (unpackOrMaskSwizzle) {
188 if (colorManagement) {
189 if (downscale) {
190 MOZ_ASSERT(!blendAnimation);
191 if (removeFrameRect) {
192 if (deinterlace) {
193 pipe = MakePipe(swizzleConfig, deinterlacingConfig,
194 removeFrameRectConfig, downscalingConfig,
195 colorManagementConfig, surfaceConfig);
196 } else if (adam7Interpolate) {
197 pipe = MakePipe(swizzleConfig, interpolatingConfig,
198 removeFrameRectConfig, downscalingConfig,
199 colorManagementConfig, surfaceConfig);
200 } else { // (deinterlace and adam7Interpolate are false)
201 pipe = MakePipe(swizzleConfig, removeFrameRectConfig,
202 downscalingConfig, colorManagementConfig,
203 surfaceConfig);
205 } else { // (removeFrameRect is false)
206 if (deinterlace) {
207 pipe = MakePipe(swizzleConfig, deinterlacingConfig,
208 downscalingConfig, colorManagementConfig,
209 surfaceConfig);
210 } else if (adam7Interpolate) {
211 pipe = MakePipe(swizzleConfig, interpolatingConfig,
212 downscalingConfig, colorManagementConfig,
213 surfaceConfig);
214 } else { // (deinterlace and adam7Interpolate are false)
215 pipe = MakePipe(swizzleConfig, downscalingConfig,
216 colorManagementConfig, surfaceConfig);
219 } else { // (downscale is false)
220 if (blendAnimation) {
221 if (deinterlace) {
222 pipe = MakePipe(swizzleConfig, deinterlacingConfig,
223 colorManagementConfig, blendAnimationConfig,
224 surfaceConfig);
225 } else if (adam7Interpolate) {
226 pipe = MakePipe(swizzleConfig, interpolatingConfig,
227 colorManagementConfig, blendAnimationConfig,
228 surfaceConfig);
229 } else { // (deinterlace and adam7Interpolate are false)
230 pipe = MakePipe(swizzleConfig, colorManagementConfig,
231 blendAnimationConfig, surfaceConfig);
233 } else if (removeFrameRect) {
234 if (deinterlace) {
235 pipe = MakePipe(swizzleConfig, deinterlacingConfig,
236 colorManagementConfig, removeFrameRectConfig,
237 surfaceConfig);
238 } else if (adam7Interpolate) {
239 pipe = MakePipe(swizzleConfig, interpolatingConfig,
240 colorManagementConfig, removeFrameRectConfig,
241 surfaceConfig);
242 } else { // (deinterlace and adam7Interpolate are false)
243 pipe = MakePipe(swizzleConfig, colorManagementConfig,
244 removeFrameRectConfig, surfaceConfig);
246 } else { // (blendAnimation and removeFrameRect is false)
247 if (deinterlace) {
248 pipe = MakePipe(swizzleConfig, deinterlacingConfig,
249 colorManagementConfig, surfaceConfig);
250 } else if (adam7Interpolate) {
251 pipe = MakePipe(swizzleConfig, interpolatingConfig,
252 colorManagementConfig, surfaceConfig);
253 } else { // (deinterlace and adam7Interpolate are false)
254 pipe =
255 MakePipe(swizzleConfig, colorManagementConfig, surfaceConfig);
259 } else { // (colorManagement is false)
260 if (downscale) {
261 MOZ_ASSERT(!blendAnimation);
262 if (removeFrameRect) {
263 if (deinterlace) {
264 pipe = MakePipe(swizzleConfig, deinterlacingConfig,
265 removeFrameRectConfig, downscalingConfig,
266 surfaceConfig);
267 } else if (adam7Interpolate) {
268 pipe = MakePipe(swizzleConfig, interpolatingConfig,
269 removeFrameRectConfig, downscalingConfig,
270 surfaceConfig);
271 } else { // (deinterlace and adam7Interpolate are false)
272 pipe = MakePipe(swizzleConfig, removeFrameRectConfig,
273 downscalingConfig, surfaceConfig);
275 } else { // (removeFrameRect is false)
276 if (deinterlace) {
277 pipe = MakePipe(swizzleConfig, deinterlacingConfig,
278 downscalingConfig, surfaceConfig);
279 } else if (adam7Interpolate) {
280 pipe = MakePipe(swizzleConfig, interpolatingConfig,
281 downscalingConfig, surfaceConfig);
282 } else { // (deinterlace and adam7Interpolate are false)
283 pipe = MakePipe(swizzleConfig, downscalingConfig, surfaceConfig);
286 } else { // (downscale is false)
287 if (blendAnimation) {
288 if (deinterlace) {
289 pipe = MakePipe(swizzleConfig, deinterlacingConfig,
290 blendAnimationConfig, surfaceConfig);
291 } else if (adam7Interpolate) {
292 pipe = MakePipe(swizzleConfig, interpolatingConfig,
293 blendAnimationConfig, surfaceConfig);
294 } else { // (deinterlace and adam7Interpolate are false)
295 pipe =
296 MakePipe(swizzleConfig, blendAnimationConfig, surfaceConfig);
298 } else if (removeFrameRect) {
299 if (deinterlace) {
300 pipe = MakePipe(swizzleConfig, deinterlacingConfig,
301 removeFrameRectConfig, surfaceConfig);
302 } else if (adam7Interpolate) {
303 pipe = MakePipe(swizzleConfig, interpolatingConfig,
304 removeFrameRectConfig, surfaceConfig);
305 } else { // (deinterlace and adam7Interpolate are false)
306 pipe =
307 MakePipe(swizzleConfig, removeFrameRectConfig, surfaceConfig);
309 } else { // (blendAnimation and removeFrameRect is false)
310 if (deinterlace) {
311 pipe =
312 MakePipe(swizzleConfig, deinterlacingConfig, surfaceConfig);
313 } else if (adam7Interpolate) {
314 pipe =
315 MakePipe(swizzleConfig, interpolatingConfig, surfaceConfig);
316 } else { // (deinterlace and adam7Interpolate are false)
317 pipe = MakePipe(swizzleConfig, surfaceConfig);
322 } else if (swapOrAlphaSwizzle) {
323 if (colorManagement) {
324 if (downscale) {
325 MOZ_ASSERT(!blendAnimation);
326 if (removeFrameRect) {
327 if (deinterlace) {
328 pipe = MakePipe(colorManagementConfig, swizzleConfig,
329 deinterlacingConfig, removeFrameRectConfig,
330 downscalingConfig, surfaceConfig);
331 } else if (adam7Interpolate) {
332 pipe = MakePipe(colorManagementConfig, swizzleConfig,
333 interpolatingConfig, removeFrameRectConfig,
334 downscalingConfig, surfaceConfig);
335 } else { // (deinterlace and adam7Interpolate are false)
336 pipe = MakePipe(colorManagementConfig, swizzleConfig,
337 removeFrameRectConfig, downscalingConfig,
338 surfaceConfig);
340 } else { // (removeFrameRect is false)
341 if (deinterlace) {
342 pipe = MakePipe(colorManagementConfig, swizzleConfig,
343 deinterlacingConfig, downscalingConfig,
344 surfaceConfig);
345 } else if (adam7Interpolate) {
346 pipe = MakePipe(colorManagementConfig, swizzleConfig,
347 interpolatingConfig, downscalingConfig,
348 surfaceConfig);
349 } else { // (deinterlace and adam7Interpolate are false)
350 pipe = MakePipe(colorManagementConfig, swizzleConfig,
351 downscalingConfig, surfaceConfig);
354 } else { // (downscale is false)
355 if (blendAnimation) {
356 if (deinterlace) {
357 pipe = MakePipe(colorManagementConfig, swizzleConfig,
358 deinterlacingConfig, blendAnimationConfig,
359 surfaceConfig);
360 } else if (adam7Interpolate) {
361 pipe = MakePipe(colorManagementConfig, swizzleConfig,
362 interpolatingConfig, blendAnimationConfig,
363 surfaceConfig);
364 } else { // (deinterlace and adam7Interpolate are false)
365 pipe = MakePipe(colorManagementConfig, swizzleConfig,
366 blendAnimationConfig, surfaceConfig);
368 } else if (removeFrameRect) {
369 if (deinterlace) {
370 pipe = MakePipe(colorManagementConfig, swizzleConfig,
371 deinterlacingConfig, removeFrameRectConfig,
372 surfaceConfig);
373 } else if (adam7Interpolate) {
374 pipe = MakePipe(colorManagementConfig, swizzleConfig,
375 interpolatingConfig, removeFrameRectConfig,
376 surfaceConfig);
377 } else { // (deinterlace and adam7Interpolate are false)
378 pipe = MakePipe(colorManagementConfig, swizzleConfig,
379 removeFrameRectConfig, surfaceConfig);
381 } else { // (blendAnimation and removeFrameRect is false)
382 if (deinterlace) {
383 pipe = MakePipe(colorManagementConfig, swizzleConfig,
384 deinterlacingConfig, surfaceConfig);
385 } else if (adam7Interpolate) {
386 pipe = MakePipe(colorManagementConfig, swizzleConfig,
387 interpolatingConfig, surfaceConfig);
388 } else { // (deinterlace and adam7Interpolate are false)
389 pipe =
390 MakePipe(colorManagementConfig, swizzleConfig, surfaceConfig);
394 } else { // (colorManagement is false)
395 if (downscale) {
396 MOZ_ASSERT(!blendAnimation);
397 if (removeFrameRect) {
398 if (deinterlace) {
399 pipe = MakePipe(swizzleConfig, deinterlacingConfig,
400 removeFrameRectConfig, downscalingConfig,
401 surfaceConfig);
402 } else if (adam7Interpolate) {
403 pipe = MakePipe(swizzleConfig, interpolatingConfig,
404 removeFrameRectConfig, downscalingConfig,
405 surfaceConfig);
406 } else { // (deinterlace and adam7Interpolate are false)
407 pipe = MakePipe(swizzleConfig, removeFrameRectConfig,
408 downscalingConfig, surfaceConfig);
410 } else { // (removeFrameRect is false)
411 if (deinterlace) {
412 pipe = MakePipe(swizzleConfig, deinterlacingConfig,
413 downscalingConfig, surfaceConfig);
414 } else if (adam7Interpolate) {
415 pipe = MakePipe(swizzleConfig, interpolatingConfig,
416 downscalingConfig, surfaceConfig);
417 } else { // (deinterlace and adam7Interpolate are false)
418 pipe = MakePipe(swizzleConfig, downscalingConfig, surfaceConfig);
421 } else { // (downscale is false)
422 if (blendAnimation) {
423 if (deinterlace) {
424 pipe = MakePipe(swizzleConfig, deinterlacingConfig,
425 blendAnimationConfig, surfaceConfig);
426 } else if (adam7Interpolate) {
427 pipe = MakePipe(swizzleConfig, interpolatingConfig,
428 blendAnimationConfig, surfaceConfig);
429 } else { // (deinterlace and adam7Interpolate are false)
430 pipe =
431 MakePipe(swizzleConfig, blendAnimationConfig, surfaceConfig);
433 } else if (removeFrameRect) {
434 if (deinterlace) {
435 pipe = MakePipe(swizzleConfig, deinterlacingConfig,
436 removeFrameRectConfig, surfaceConfig);
437 } else if (adam7Interpolate) {
438 pipe = MakePipe(swizzleConfig, interpolatingConfig,
439 removeFrameRectConfig, surfaceConfig);
440 } else { // (deinterlace and adam7Interpolate are false)
441 pipe =
442 MakePipe(swizzleConfig, removeFrameRectConfig, surfaceConfig);
444 } else { // (blendAnimation and removeFrameRect is false)
445 if (deinterlace) {
446 pipe =
447 MakePipe(swizzleConfig, deinterlacingConfig, surfaceConfig);
448 } else if (adam7Interpolate) {
449 pipe =
450 MakePipe(swizzleConfig, interpolatingConfig, surfaceConfig);
451 } else { // (deinterlace and adam7Interpolate are false)
452 pipe = MakePipe(swizzleConfig, surfaceConfig);
457 } else { // (unpackOrMaskSwizzle and swapOrAlphaSwizzle are false)
458 if (colorManagement) {
459 if (downscale) {
460 MOZ_ASSERT(!blendAnimation);
461 if (removeFrameRect) {
462 if (deinterlace) {
463 pipe = MakePipe(deinterlacingConfig, removeFrameRectConfig,
464 downscalingConfig, colorManagementConfig,
465 surfaceConfig);
466 } else if (adam7Interpolate) {
467 pipe = MakePipe(interpolatingConfig, removeFrameRectConfig,
468 downscalingConfig, colorManagementConfig,
469 surfaceConfig);
470 } else { // (deinterlace and adam7Interpolate are false)
471 pipe = MakePipe(removeFrameRectConfig, downscalingConfig,
472 colorManagementConfig, surfaceConfig);
474 } else { // (removeFrameRect is false)
475 if (deinterlace) {
476 pipe = MakePipe(deinterlacingConfig, downscalingConfig,
477 colorManagementConfig, surfaceConfig);
478 } else if (adam7Interpolate) {
479 pipe = MakePipe(interpolatingConfig, downscalingConfig,
480 colorManagementConfig, surfaceConfig);
481 } else { // (deinterlace and adam7Interpolate are false)
482 pipe = MakePipe(downscalingConfig, colorManagementConfig,
483 surfaceConfig);
486 } else { // (downscale is false)
487 if (blendAnimation) {
488 if (deinterlace) {
489 pipe = MakePipe(deinterlacingConfig, colorManagementConfig,
490 blendAnimationConfig, surfaceConfig);
491 } else if (adam7Interpolate) {
492 pipe = MakePipe(interpolatingConfig, colorManagementConfig,
493 blendAnimationConfig, surfaceConfig);
494 } else { // (deinterlace and adam7Interpolate are false)
495 pipe = MakePipe(colorManagementConfig, blendAnimationConfig,
496 surfaceConfig);
498 } else if (removeFrameRect) {
499 if (deinterlace) {
500 pipe = MakePipe(deinterlacingConfig, colorManagementConfig,
501 removeFrameRectConfig, surfaceConfig);
502 } else if (adam7Interpolate) {
503 pipe = MakePipe(interpolatingConfig, colorManagementConfig,
504 removeFrameRectConfig, surfaceConfig);
505 } else { // (deinterlace and adam7Interpolate are false)
506 pipe = MakePipe(colorManagementConfig, removeFrameRectConfig,
507 surfaceConfig);
509 } else { // (blendAnimation and removeFrameRect is false)
510 if (deinterlace) {
511 pipe = MakePipe(deinterlacingConfig, colorManagementConfig,
512 surfaceConfig);
513 } else if (adam7Interpolate) {
514 pipe = MakePipe(interpolatingConfig, colorManagementConfig,
515 surfaceConfig);
516 } else { // (deinterlace and adam7Interpolate are false)
517 pipe = MakePipe(colorManagementConfig, surfaceConfig);
521 } else { // (colorManagement is false)
522 if (downscale) {
523 MOZ_ASSERT(!blendAnimation);
524 if (removeFrameRect) {
525 if (deinterlace) {
526 pipe = MakePipe(deinterlacingConfig, removeFrameRectConfig,
527 downscalingConfig, surfaceConfig);
528 } else if (adam7Interpolate) {
529 pipe = MakePipe(interpolatingConfig, removeFrameRectConfig,
530 downscalingConfig, surfaceConfig);
531 } else { // (deinterlace and adam7Interpolate are false)
532 pipe = MakePipe(removeFrameRectConfig, downscalingConfig,
533 surfaceConfig);
535 } else { // (removeFrameRect is false)
536 if (deinterlace) {
537 pipe = MakePipe(deinterlacingConfig, downscalingConfig,
538 surfaceConfig);
539 } else if (adam7Interpolate) {
540 pipe = MakePipe(interpolatingConfig, downscalingConfig,
541 surfaceConfig);
542 } else { // (deinterlace and adam7Interpolate are false)
543 pipe = MakePipe(downscalingConfig, surfaceConfig);
546 } else { // (downscale is false)
547 if (blendAnimation) {
548 if (deinterlace) {
549 pipe = MakePipe(deinterlacingConfig, blendAnimationConfig,
550 surfaceConfig);
551 } else if (adam7Interpolate) {
552 pipe = MakePipe(interpolatingConfig, blendAnimationConfig,
553 surfaceConfig);
554 } else { // (deinterlace and adam7Interpolate are false)
555 pipe = MakePipe(blendAnimationConfig, surfaceConfig);
557 } else if (removeFrameRect) {
558 if (deinterlace) {
559 pipe = MakePipe(deinterlacingConfig, removeFrameRectConfig,
560 surfaceConfig);
561 } else if (adam7Interpolate) {
562 pipe = MakePipe(interpolatingConfig, removeFrameRectConfig,
563 surfaceConfig);
564 } else { // (deinterlace and adam7Interpolate are false)
565 pipe = MakePipe(removeFrameRectConfig, surfaceConfig);
567 } else { // (blendAnimation and removeFrameRect is false)
568 if (deinterlace) {
569 pipe = MakePipe(deinterlacingConfig, surfaceConfig);
570 } else if (adam7Interpolate) {
571 pipe = MakePipe(interpolatingConfig, surfaceConfig);
572 } else { // (deinterlace and adam7Interpolate are false)
573 pipe = MakePipe(surfaceConfig);
580 return pipe;
583 private:
584 template <typename... Configs>
585 static Maybe<SurfacePipe> MakePipe(const Configs&... aConfigs) {
586 auto pipe = MakeUnique<typename detail::FilterPipeline<Configs...>::Type>();
587 nsresult rv = pipe->Configure(aConfigs...);
588 if (NS_FAILED(rv)) {
589 return Nothing();
592 return Some(SurfacePipe{std::move(pipe)});
595 virtual ~SurfacePipeFactory() = 0;
598 } // namespace image
599 } // namespace mozilla
601 #endif // mozilla_image_SurfacePipeFactory_h