summaryrefslogtreecommitdiff
path: root/Userland/Libraries/LibGfx/PNGShared.h
blob: 299fceb29e60532d334adeabd1505def410ee7bb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
/*
 * Copyright (c) 2022, the SerenityOS developers.
 *
 * SPDX-License-Identifier: BSD-2-Clause
 */

#pragma once

#include <AK/Array.h>
#include <AK/SIMD.h>

namespace Gfx::PNG {

// https://www.w3.org/TR/PNG/#5PNG-file-signature
static constexpr Array<u8, 8> header = { 0x89, 'P', 'N', 'G', 13, 10, 26, 10 };

// https://www.w3.org/TR/PNG/#6Colour-values
enum class ColorType : u8 {
    Greyscale = 0,
    Truecolor = 2, // RGB
    IndexedColor = 3,
    GreyscaleWithAlpha = 4,
    TruecolorWithAlpha = 6,
};

// https://www.w3.org/TR/PNG/#9Filter-types
enum class FilterType : u8 {
    None,
    Sub,
    Up,
    Average,
    Paeth,
};

// https://www.w3.org/TR/PNG/#9Filter-type-4-Paeth
ALWAYS_INLINE u8 paeth_predictor(u8 a, u8 b, u8 c)
{
    int p = a + b - c;
    int pa = AK::abs(p - a);
    int pb = AK::abs(p - b);
    int pc = AK::abs(p - c);
    if (pa <= pb && pa <= pc)
        return a;
    if (pb <= pc)
        return b;
    return c;
}

ALWAYS_INLINE AK::SIMD::u8x4 paeth_predictor(AK::SIMD::u8x4 a, AK::SIMD::u8x4 b, AK::SIMD::u8x4 c)
{
    return AK::SIMD::u8x4 {
        paeth_predictor(a[0], b[0], c[0]),
        paeth_predictor(a[1], b[1], c[1]),
        paeth_predictor(a[2], b[2], c[2]),
        paeth_predictor(a[3], b[3], c[3]),
    };
}

};