summaryrefslogtreecommitdiffstats
path: root/spudec.c
diff options
context:
space:
mode:
authorreimar <reimar@b3059339-0415-0410-9bf9-f77b7e298cf2>2010-07-24 21:24:20 +0000
committerUoti Urpala <uau@glyph.nonexistent.invalid>2010-11-02 04:14:45 +0200
commitaf62b02a637faaaf0633f4d4a8bf06aa36e95baa (patch)
treec4f08310a517e56c419e1d6d3a18cda774e543dc /spudec.c
parentdd886133a9d09980a95278d775112debef80c924 (diff)
downloadmpv-af62b02a637faaaf0633f4d4a8bf06aa36e95baa.tar.bz2
mpv-af62b02a637faaaf0633f4d4a8bf06aa36e95baa.tar.xz
spudec: Share paletted -> gray/alpha conversion code
Also keep a copy of the raw rle-decoded data. Should simplify implementing palette changes and the rle decoding code. git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@31789 b3059339-0415-0410-9bf9-f77b7e298cf2
Diffstat (limited to 'spudec.c')
-rw-r--r--spudec.c75
1 files changed, 43 insertions, 32 deletions
diff --git a/spudec.c b/spudec.c
index 0b7ef44d9b..904fb69126 100644
--- a/spudec.c
+++ b/spudec.c
@@ -98,6 +98,7 @@ typedef struct {
size_t image_size; /* Size of the image buffer */
unsigned char *image; /* Grayscale value */
unsigned char *aimage; /* Alpha value */
+ unsigned char *pal_image; /* palette entry value */
unsigned int scaled_frame_width, scaled_frame_height;
unsigned int scaled_start_col, scaled_start_row;
unsigned int scaled_width, scaled_height, scaled_stride;
@@ -229,18 +230,42 @@ static int spudec_alloc_image(spudec_handle_t *this, int stride, int height)
free(this->image);
this->image_size = 0;
}
- this->image = malloc(2 * this->stride * this->height);
+ this->image = malloc(3 * this->stride * this->height);
if (this->image) {
this->image_size = this->stride * this->height;
this->aimage = this->image + this->image_size;
+ this->pal_image = this->aimage + this->image_size;
}
}
return this->image != NULL;
}
+/**
+ * \param pal palette in MPlayer-style gray-alpha values, i.e.
+ * alpha == 0 means transparent, 1 fully opaque,
+ * gray value <= 256 - alpha.
+ */
+static void pal2gray_alpha(const uint16_t *pal,
+ const uint8_t *src, int src_stride,
+ uint8_t *dst, uint8_t *dsta,
+ int dst_stride, int w, int h)
+{
+ int x, y;
+ for (y = 0; y < h; y++) {
+ for (x = 0; x < w; x++) {
+ uint16_t pixel = pal[src[x]];
+ *dst++ = pixel;
+ *dsta++ = pixel >> 8;
+ }
+ for (; x < dst_stride; x++)
+ *dsta++ = *dst++ = 0;
+ src += src_stride;
+ }
+}
+
static void spudec_process_data(spudec_handle_t *this, packet_t *packet)
{
- unsigned int cmap[4], alpha[4];
+ uint16_t pal[4];
unsigned int i, x, y;
this->scaled_frame_width = 0;
@@ -253,30 +278,23 @@ static void spudec_process_data(spudec_handle_t *this, packet_t *packet)
this->width = packet->width;
this->stride = packet->stride;
for (i = 0; i < 4; ++i) {
- alpha[i] = packet->alpha[i];
+ int color;
+ int alpha = packet->alpha[i];
// extend 4 -> 8 bit
- alpha[i] |= alpha[i] << 4;
+ alpha |= alpha << 4;
if (this->custom && (this->cuspal[i] >> 31) != 0)
- alpha[i] = 0;
- cmap[i] = this->custom ? this->cuspal[i] :
- this->global_palette[packet->palette[i]];
- cmap[i] = (cmap[i] >> 16) & 0xff;
- // convert to MPlayer format
- cmap[i] = FFMIN(cmap[i], alpha[i]);
- alpha[i] = -alpha[i];
+ alpha = 0;
+ color = this->custom ? this->cuspal[i] :
+ this->global_palette[packet->palette[i]];
+ color = (color >> 16) & 0xff;
+ // convert to MPlayer-style gray/alpha palette
+ color = FFMIN(color, alpha);
+ pal[i] = (-alpha << 8) | color;
}
if (!spudec_alloc_image(this, this->stride, this->height))
return;
- /* Kludge: draw_alpha needs width multiple of 8. */
- if (this->width < this->stride)
- for (y = 0; y < this->height; ++y) {
- memset(this->aimage + y * this->stride + this->width, 0, this->stride - this->width);
- /* FIXME: Why is this one needed? */
- memset(this->image + y * this->stride + this->width, 0, this->stride - this->width);
- }
-
i = packet->current_nibble[1];
x = 0;
y = 0;
@@ -301,9 +319,7 @@ static void spudec_process_data(spudec_handle_t *this, packet_t *packet)
len = rle >> 2;
if (len > this->width - x || len == 0)
len = this->width - x;
- /* FIXME have to use palette and alpha map*/
- memset(this->image + y * this->stride + x, cmap[color], len);
- memset(this->aimage + y * this->stride + x, alpha[color], len);
+ memset(this->pal_image + y * this->stride + x, color, len);
x += len;
if (x >= this->width) {
next_line(packet);
@@ -311,6 +327,9 @@ static void spudec_process_data(spudec_handle_t *this, packet_t *packet)
++y;
}
}
+ pal2gray_alpha(pal, this->pal_image, this->stride,
+ this->image, this->aimage, this->stride,
+ this->width, this->height);
spudec_cut_image(this);
}
@@ -1302,16 +1321,8 @@ void spudec_set_paletted(void *this, const uint8_t *pal_img, int pal_stride,
gray = FFMIN(gray, alpha);
g8a8_pal[i] = (-alpha << 8) | gray;
}
- for (y = 0; y < h; y++) {
- for (x = 0; x < w; x++) {
- uint16_t pixel = g8a8_pal[pal_img[x]];
- *img++ = pixel;
- *aimg++ = pixel >> 8;
- }
- for (; x < stride; x++)
- *aimg++ = *img++ = 0;
- pal_img += pal_stride;
- }
+ pal2gray_alpha(g8a8_pal, pal_img, pal_stride,
+ img, aimg, stride, w, h);
packet->start_pts = 0;
packet->end_pts = 0x7fffffff;
if (pts != MP_NOPTS_VALUE)