source: abuse/branches/lol/src/imlib/filter.cpp @ 732

Last change on this file since 732 was 732, checked in by Sam Hocevar, 8 years ago

build: SDL2 compilation fixes.

File size: 3.6 KB
Line 
1/*
2 *  Abuse - dark 2D side-scrolling platform game
3 *  Copyright (c) 1995 Crack dot Com
4 *  Copyright (c) 2005-2013 Sam Hocevar <sam@hocevar.net>
5 *
6 *  This software was released into the Public Domain. As with most public
7 *  domain software, no warranty is made or implied by Crack dot Com, by
8 *  Jonathan Clark, or by Sam Hocevar.
9 */
10
11#if HAVE_CONFIG_H
12#   include "config.h"
13#endif
14
15#include "common.h"
16
17#include "imlib/image.h"
18#include "imlib/filter.h"
19
20Filter::Filter(int colors)
21{
22    ASSERT(colors >= 0 && colors <= 256, "bad color count");
23
24    m_table.Resize(colors, 0);
25}
26
27// Creates a conversion filter from one palette to another
28Filter::Filter(Palette *from, Palette *to)
29{
30    int size = lol::max(from->Count(), to->Count());
31    m_table.Resize(size);
32
33    int dk = to->FindDarkest(1);
34
35    for (int i = 0; i < size; i++)
36    {
37        u8vec3 color = from->GetColor(i);
38        int n = to->FindClosest(color);
39
40        // Make sure non-blacks don't get remapped to the transparency
41        if (color != u8vec3::zero && to->GetColor(n) == u8vec3::zero)
42            n = dk;
43
44        m_table[i] = n;
45    }
46}
47
48Filter::~Filter()
49{
50}
51
52void Filter::Set(int color_num, int change_to)
53{
54    ASSERT(color_num >= 0 && color_num < m_table.Count(), "Bad colors_num");
55
56    m_table[color_num] = change_to;
57}
58
59void Filter::Apply(AImage *im)
60{
61    uint8_t *dst = im->scan_line(0);
62    int npixels = im->Size().x * im->Size().y;
63    while (npixels--)
64    {
65        *dst = m_table[*dst];
66        ++dst;
67    }
68}
69
70/* This is only ever used in the editor, when showing the toolbar. It
71 * does not look like it's very useful. */
72void Filter::PutImage(AImage *screen, AImage *im, ivec2 pos)
73{
74    ivec2 aa = ivec2::zero, bb = im->Size(), caa, cbb;
75    screen->GetClip(caa, cbb);
76
77    // See if the image gets clipped off the screen
78    if (!(pos < cbb && pos + (bb - aa) > caa))
79        return;
80
81    aa += lol::max(caa - pos, ivec2::zero);
82    pos = lol::max(pos, caa);
83    bb = lol::min(bb, cbb - pos + aa);
84
85    if (!(aa < bb))
86        return;
87
88    ivec2 span = bb - aa;
89
90    screen->AddDirty(pos, pos + span);
91
92    for (int j = 0; j < span.y; j++)
93    {
94        uint8_t *src = im->scan_line(aa.y + j) + aa.x;
95        uint8_t *dst = screen->scan_line(pos.y + j) + pos.x;
96
97        for (int i = 0; i < span.x; i++, src++, dst++)
98            if (*src)
99                *dst = m_table[*src];
100    }
101}
102
103ColorFilter::ColorFilter(Palette *pal, int color_bits)
104{
105    int max = pal->Count();
106    int mul = 1 << (8 - color_bits);
107    m_size = 1 << color_bits;
108    m_table.Resize(m_size * m_size * m_size);
109
110    /* For each colour in the RGB cube, find the nearest palette element. */
111    for (int r = 0; r < m_size; r++)
112    for (int g = 0; g < m_size; g++)
113    for (int b = 0; b < m_size; b++)
114    {
115        ivec3 rgb = ivec3(r, g, b) * mul;
116        int best = 256 * 256 * 3;
117        int n = 0;
118
119        for (int i = 0; i < max; i++)
120        {
121            int dist = sqlength(rgb - (ivec3)pal->GetColor(i));
122            if (dist < best)
123            {
124                best = dist;
125                n = i;
126            }
127        }
128        m_table[(r * m_size + g) * m_size + b] = n;
129    }
130}
131
132ColorFilter::ColorFilter(SpecEntry *e, bFILE *fp)
133{
134    fp->seek(e->offset, 0);
135    m_size = fp->read_uint16();
136    m_table.Resize(m_size * m_size * m_size);
137    fp->read(m_table.Data(), m_table.Bytes());
138}
139
140ColorFilter::~ColorFilter()
141{
142}
143
144size_t ColorFilter::DiskUsage()
145{
146    return sizeof(uint16_t) + m_table.Bytes();
147}
148
149int ColorFilter::Write(bFILE *fp)
150{
151    fp->write_uint16(m_size);
152    return fp->write(m_table.Data(), m_table.Bytes()) == m_table.Bytes();
153}
154
Note: See TracBrowser for help on using the repository browser.