summaryrefslogtreecommitdiffstats
path: root/apps/recorder/bmp.h
blob: 610ec29f2170175ceacf5821e04d7565b9fdf851 (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
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
/***************************************************************************
 *             __________               __   ___.
 *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
 *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
 *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
 *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
 *                     \/            \/     \/    \/            \/
 * $Id$
 *
 * Copyright (C) 2002 by Daniel Stenberg
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
 * KIND, either express or implied.
 *
 ****************************************************************************/
#ifndef _BMP_H_
#define _BMP_H_

#include "config.h"
#include "lcd.h"
#include "inttypes.h"
#include "resize.h"
#ifdef HAVE_REMOTE_LCD
#include "lcd-remote.h"
#endif

#define ARRAY_SIZE(array)    (int)(sizeof(array)/(sizeof(array[0])))

#define IMG_NORESIZE           0
#define IMG_RESIZE             1
#define BM_MAX_WIDTH (((LCD_WIDTH) + 7) & ~7)

struct uint8_rgb {
    /* Little endian */
    uint8_t blue;
    uint8_t green;
    uint8_t red;
    uint8_t alpha;
};

struct dim {
    short width;
    short height;
};

struct rowset {
    short rowstep;
    short rowstart;
    short rowstop;
};

#if (LCD_DEPTH > 1) || defined(HAVE_REMOTE_LCD) && (LCD_REMOTE_DEPTH > 1)
extern const unsigned char dither_table[16];
#define DITHERY(y) (dither_table[(y) & 15] & 0xAA)
#define DITHERX(x) (dither_table[(x) & 15])
#define DITHERXDY(x,dy) (DITHERX(x) ^ dy)
#define DITHERDXY(dx,y) (dx ^ DITHERY(y))
#define DITHERXY(x,y) (DITHERX(x) ^ DITHERY(y))
#endif

/* The /256 version has a mean squared variance from YUV luma of <1 grey level.
   The /8 version is a good deal less accurate, but sufficient on mono as we
   don't support HQ output or dithering there, yet.
*/
static inline unsigned brightness(struct uint8_rgb color)
{
#if LCD_DEPTH > 1 || defined(PLUGIN)
    return (77 * (unsigned)color.red + 150 * (unsigned)color.green
              + 29 * (unsigned)color.blue) / 256;
#else
    return (2 * (unsigned)color.red + 5 * (unsigned)color.green
              + (unsigned)color.blue) / 8;
#endif
}

#if ((LCD_DEPTH == 2) && (LCD_PIXELFORMAT == VERTICAL_INTERLEAVED)) \
 || (defined(HAVE_REMOTE_LCD) && (LCD_REMOTE_DEPTH == 2) \
     && (LCD_REMOTE_PIXELFORMAT == VERTICAL_INTERLEAVED))
extern const unsigned short vi_pattern[4];
#endif

/* Number of rows of data in a mono bitmap height pixels tall */
#define MONO_BM_HEIGHT(height) (((height) + 7) >> 3)

/* Number of rows of datain a LCD native bitmap height pixels tall */
#if LCD_DEPTH > 1 || (defined(HAVE_REMOTE_LCD) && LCD_REMOTE_DEPTH > 1)
#if LCD_DEPTH == 1 || \
    (LCD_DEPTH == 2 && LCD_PIXELFORMAT == VERTICAL_INTERLEAVED)
#define LCD_BM_HEIGHT(height) (((height) + 7) >> 3)
#elif LCD_DEPTH == 2 && LCD_PIXELFORMAT == VERTICAL_PACKING
#define LCD_BM_HEIGHT(height) (((height) + 3) >> 2)
#else
#define LCD_BM_HEIGHT(height) (height)
#endif

/* Number of rows of data in a remote native bitmap height pixels tall. */
#ifdef HAVE_REMOTE_LCD
#if LCD_REMOTE_DEPTH == 1 || \
    (LCD_REMOTE_DEPTH == 2 && LCD_REMOTE_PIXELFORMAT == VERTICAL_INTERLEAVED)
#define LCD_REMOTE_BM_HEIGHT(height) (((height) + 7) >> 3)
#elif LCD_REMOTE_DEPTH == 2 && LCD_REMOTE_PIXELFORMAT == VERTICAL_PACKING
#define LCD_REMOTE_BM_HEIGHT(height) (((height) + 3) >> 2)
#else
#define LCD_REMOTE_BM_HEIGHT(height) (height)
#endif
#define NATIVE_BM_HEIGHT(height,remote) ((remote) ? \
        LCD_REMOTE_BM_HEIGHT(height) : LCD_BM_HEIGHT(height))
#else
#define NATIVE_BM_HEIGHT(height,remote) LCD_BM_HEIGHT(height)
#endif

/* Convenience macro to calculate rows based on height, remote vs main LCD,
   and format
*/
#define BM_HEIGHT(height,format,remote) ((format) == FORMAT_MONO ? \
    MONO_BM_HEIGHT(height) : NATIVE_BM_HEIGHT(height,remote))
#else
#define BM_HEIGHT(height,format,remote) MONO_BM_HEIGHT(height)
#endif

/* Number of data elements in a mono bitmap width pixels wide */
#define MONO_BM_WIDTH(width) (width)

/* Number of data elements in a LCD native bitmap width pixels wide */
#if LCD_DEPTH > 1
#if LCD_DEPTH == 2 && LCD_PIXELFORMAT == HORIZONTAL_PACKING
#define LCD_BM_WIDTH(width) (((width) + 3) >> 2)
#else
#define LCD_BM_WIDTH(width) (width)
#endif

/* Number of data elements in a remote native bitmap width pixels wide */
#ifdef HAVE_REMOTE_LCD
#if LCD_REMOTE_DEPTH == 2 && LCD_REMOTE_PIXELFORMAT == HORIZONTAL_PACKING
#define LCD_REMOTE_BM_WIDTH(width) (((width) + 3) >> 2)
#else
#define LCD_REMOTE_BM_WIDTH(width) (width)
#endif
#define NATIVE_BM_WIDTH(width,remote) ((remote) ? \
    LCD_REMOTE_BM_WIDTH(width) : LCD_BM_WIDTH(width))
#else
#define NATIVE_BM_WIDTH(width,remote) LCD_BM_WIDTH(width)
#endif

/* Convenience macro to calculate elements based on height, remote vs native
   main LCD, and format
*/
#define BM_WIDTH(width,format,remote) ((format) == FORMAT_MONO ? \
    MONO_BM_WIDTH(width) : NATIVE_BM_WIDTH(width,remote))
#else
#define BM_WIDTH(width,format,remote) MONO_BM_WIDTH(width)
#endif

/* Size in bytes of a mono bitmap of dimensions width*height */
#define MONO_BM_SIZE(width,height) (MONO_BM_WIDTH(width) * \
    MONO_BM_HEIGHT(height) * FB_DATA_SZ)

/* Size in bytes of a native bitmap of dimensions width*height */
#if LCD_DEPTH > 1 || (defined(HAVE_REMOTE_LCD) && LCD_REMOTE_DEPTH > 1)
#if defined(HAVE_REMOTE_LCD) && FB_DATA_SZ != FB_RDATA_SZ
#define NATIVE_BM_SIZE(width,height,format,remote) \
    (((remote) ? FB_RDATA_SZ : FB_DATA_SZ) * BM_WIDTH(width,format,remote) \
    * BM_HEIGHT(height,format,remote))
#else
#define NATIVE_BM_SIZE(width,height,format,remote) \
    (FB_DATA_SZ * BM_WIDTH(width,format,remote) * \
    BM_HEIGHT(height,format,remote))
#endif

/* Convenience macro to calculate size in bytes based on height, remote vs
   main LCD, and format
*/
#define BM_SIZE(width,height,format,remote) (((format) == FORMAT_MONO) ? \
    MONO_BM_SIZE(width,height) : NATIVE_BM_SIZE(width,height,format,remote))
#else
#define BM_SIZE(width,height,format,remote) MONO_BM_SIZE(width,height)
#endif

/* Size in bytes needed to load and scale a bitmap with target size up to
   width*height, including overhead to allow for buffer alignment.
*/
#ifdef HAVE_LCD_COLOR
#define BM_SCALED_SIZE(width,height,format,remote) \
    (BM_SIZE(width,height,format,remote) + \
    (remote ? 0 : BM_WIDTH(width,format,remote) * sizeof(uint32_t) * 9 + 3))
#else
#define BM_SCALED_SIZE(width,height,format,remote) \
    (BM_SIZE(width,height,format,remote) + \
    (width * sizeof(uint32_t) * 3 + 3))
#endif

/*********************************************************************
 * read_bmp_file()
 *
 * Reads a 8bit BMP file and puts the data in a 1-pixel-per-byte
 * array.
 * Returns < 0 for error, or number of bytes used from the bitmap buffer
 *
 **********************************************/
int read_bmp_file(const char* filename,
                  struct bitmap *bm,
                  int maxsize,
                  int format,
                  const struct custom_format *cformat);

int read_bmp_fd(int fd,
                struct bitmap *bm,
                int maxsize,
                int format,
                const struct custom_format *cformat);

#if LCD_DEPTH > 1 && (defined(PLUGIN) || defined(HAVE_BMP_SCALING) || defined(HAVE_JPEG))
void output_row_8_native(uint32_t row, void * row_in,
                         struct scaler_context *ctx);
#endif
#endif