Bug 835381 - Update libnestegg to 38c83d9d4c0c5c84373aa285bd30094a12d6b6f6. r=kinetik
[gecko.git] / gfx / thebes / gfxAlphaRecovery.cpp
blob5c0e29b24a28b93cc1fdd4b2a45516257da131cc
1 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2 * This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 #include "gfxAlphaRecovery.h"
8 #include "gfxImageSurface.h"
10 #define MOZILLA_SSE_INCLUDE_HEADER_FOR_SSE2
11 #include "mozilla/SSE.h"
13 /* static */ bool
14 gfxAlphaRecovery::RecoverAlpha(gfxImageSurface* blackSurf,
15 const gfxImageSurface* whiteSurf,
16 Analysis* analysis)
18 gfxIntSize size = blackSurf->GetSize();
20 if (size != whiteSurf->GetSize() ||
21 (blackSurf->Format() != gfxASurface::ImageFormatARGB32 &&
22 blackSurf->Format() != gfxASurface::ImageFormatRGB24) ||
23 (whiteSurf->Format() != gfxASurface::ImageFormatARGB32 &&
24 whiteSurf->Format() != gfxASurface::ImageFormatRGB24))
25 return false;
27 #ifdef MOZILLA_MAY_SUPPORT_SSE2
28 if (!analysis && mozilla::supports_sse2() &&
29 RecoverAlphaSSE2(blackSurf, whiteSurf)) {
30 return true;
32 #endif
34 blackSurf->Flush();
35 whiteSurf->Flush();
37 unsigned char* blackData = blackSurf->Data();
38 unsigned char* whiteData = whiteSurf->Data();
40 /* Get the alpha value of 'first' */
41 uint32_t first;
42 if (size.width == 0 || size.height == 0) {
43 first = 0;
44 } else {
45 if (!blackData || !whiteData)
46 return false;
48 first = RecoverPixel(*reinterpret_cast<uint32_t*>(blackData),
49 *reinterpret_cast<uint32_t*>(whiteData));
52 uint32_t deltas = 0;
53 for (int32_t i = 0; i < size.height; ++i) {
54 uint32_t* blackPixel = reinterpret_cast<uint32_t*>(blackData);
55 const uint32_t* whitePixel = reinterpret_cast<uint32_t*>(whiteData);
56 for (int32_t j = 0; j < size.width; ++j) {
57 uint32_t recovered = RecoverPixel(blackPixel[j], whitePixel[j]);
58 blackPixel[j] = recovered;
59 deltas |= (first ^ recovered);
61 blackData += blackSurf->Stride();
62 whiteData += whiteSurf->Stride();
65 blackSurf->MarkDirty();
67 if (analysis) {
68 analysis->uniformAlpha = (deltas >> 24) == 0;
69 analysis->uniformColor = false;
70 if (analysis->uniformAlpha) {
71 double d_first_alpha = first >> 24;
72 analysis->alpha = d_first_alpha/255.0;
73 /* we only set uniformColor when the alpha is already uniform.
74 it's only useful in that case ... and if the alpha was nonuniform
75 then computing whether the color is uniform would require unpremultiplying
76 every pixel */
77 analysis->uniformColor = deltas == 0;
78 if (analysis->uniformColor) {
79 if (d_first_alpha == 0.0) {
80 /* can't unpremultiply, this is OK */
81 analysis->r = analysis->g = analysis->b = 0.0;
82 } else {
83 analysis->r = (first & 0xFF)/d_first_alpha;
84 analysis->g = ((first >> 8) & 0xFF)/d_first_alpha;
85 analysis->b = ((first >> 16) & 0xFF)/d_first_alpha;
91 return true;