Skip to content

Commit 0efd3ae

Browse files
committed
Fixed image disposition
- Fixed Background dispose mode - Added Previous dispose mode
1 parent 8526f5f commit 0efd3ae

File tree

1 file changed

+73
-41
lines changed

1 file changed

+73
-41
lines changed

xrootgif.c

Lines changed: 73 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include <stdio.h>
2626
#include <stdlib.h>
2727
#include <stdbool.h>
28+
#include <string.h>
2829
#include <X11/Xlib.h>
2930
#include <X11/Xatom.h>
3031
#include <Imlib2.h>
@@ -220,40 +221,26 @@ int load_pixmap_sample()
220221
return 0;
221222
}
222223

223-
static void render_image(GifFileType *gif, GraphicsControlBlock *gcb, SavedImage *img, DATA32 *canvas, int *color_total)
224+
static void dispose_image(GifFileType *gif, GraphicsControlBlock *gcb,
225+
SavedImage *img, DATA32 *canvas, DATA32 *old_canvas)
224226
{
225-
int num;
226-
int off, roff;
227-
GifByteType *raster;
227+
int off;
228228
GifImageDesc *desc;
229229
DATA32 c;
230230
GifColorType color;
231-
GifByteType color_code;
232231

233-
234-
raster = img->RasterBits;
235232
desc = &img->ImageDesc;
236233

237-
if(desc->ColorMap)
238-
*color_total += (num = desc->ColorMap->ColorCount);
239-
else
240-
num = gif->SColorMap->ColorCount;
241-
if(!*color_total) *color_total = num;
242-
243-
printf("\tCurrent Colors: %d, Color_Total: %d\n", num, *color_total);
244-
printf("\tDispose: ");
245-
246234
/* Select background color */
247235
if(gif->SColorMap && gif->SColorMap->ColorCount > gif->SBackGroundColor) {
248236
color = gif->SColorMap->Colors[gif->SBackGroundColor];
249237
}else {
250238
color = (GifColorType){0, 0, 0};
251239
}
252240

241+
printf("\tDispose: ");
242+
253243
switch(gcb->DisposalMode) {
254-
case DISPOSE_PREVIOUS:
255-
puts("PREVIOUS (not implemented yet)");
256-
break;
257244
case DISPOSE_BACKGROUND:
258245
puts("BACKGROUND");
259246
c = GRGBTOD32(color);
@@ -264,28 +251,66 @@ static void render_image(GifFileType *gif, GraphicsControlBlock *gcb, SavedImage
264251
}
265252
}
266253
break;
267-
case DISPOSAL_UNSPECIFIED: /* Don't dispose */
268-
printf("UNSPECIFIED, falling back to ");
269-
case DISPOSE_DO_NOT:
270-
puts("NONE");
254+
case DISPOSE_PREVIOUS:
255+
puts("PREVIOUS");
271256
for(int y = 0; y < desc->Height; ++y) {
272257
off = desc->Top*gif->SWidth + y*gif->SWidth + desc->Left;
273258
for(int x = 0; x < desc->Width; ++x) {
274-
roff = y*desc->Width;
275-
color_code = raster[roff + x];
276-
if(desc->ColorMap && desc->ColorMap->ColorCount > color_code)
277-
color = desc->ColorMap->Colors[color_code];
278-
else if(gif->SColorMap && gif->SColorMap->ColorCount > color_code)
279-
color = gif->SColorMap->Colors[color_code];
280-
else
281-
color = (GifColorType){0, 0, 0};
282-
c = GRGBTOD32(color);
283-
if(gcb->TransparentColor == -1
284-
|| gcb->TransparentColor != color_code)
285-
canvas[off + x] = c;
259+
canvas[off + x] = old_canvas[off + x];
286260
}
287261
}
288262
break;
263+
case DISPOSAL_UNSPECIFIED: printf("UNSPECIFIED, falling back to ");
264+
case DISPOSE_DO_NOT: puts("NONE");
265+
}
266+
}
267+
268+
static void render_image(GifFileType *gif, GraphicsControlBlock *gcb, SavedImage *img,
269+
DATA32 *canvas, int *color_total)
270+
{
271+
int num;
272+
int off, roff;
273+
GifByteType *raster;
274+
GifImageDesc *desc;
275+
DATA32 c;
276+
GifColorType color;
277+
GifByteType color_code;
278+
279+
280+
raster = img->RasterBits;
281+
desc = &img->ImageDesc;
282+
283+
if(desc->ColorMap)
284+
*color_total += (num = desc->ColorMap->ColorCount);
285+
else
286+
num = gif->SColorMap->ColorCount;
287+
if(!*color_total) *color_total = num;
288+
289+
printf("\tCurrent Colors: %d, Color_Total: %d\n", num, *color_total);
290+
291+
/* Select background color */
292+
if(gif->SColorMap && gif->SColorMap->ColorCount > gif->SBackGroundColor) {
293+
color = gif->SColorMap->Colors[gif->SBackGroundColor];
294+
}else {
295+
color = (GifColorType){0, 0, 0};
296+
}
297+
298+
for(int y = 0; y < desc->Height; ++y) {
299+
off = desc->Top*gif->SWidth + y*gif->SWidth + desc->Left;
300+
for(int x = 0; x < desc->Width; ++x) {
301+
roff = y*desc->Width;
302+
color_code = raster[roff + x];
303+
if(desc->ColorMap && desc->ColorMap->ColorCount > color_code)
304+
color = desc->ColorMap->Colors[color_code];
305+
else if(gif->SColorMap && gif->SColorMap->ColorCount > color_code)
306+
color = gif->SColorMap->Colors[color_code];
307+
else /* this should not happen */
308+
color = (GifColorType){0, 0, 0};
309+
c = GRGBTOD32(color);
310+
if(gcb->TransparentColor == -1
311+
|| gcb->TransparentColor != color_code)
312+
canvas[off + x] = c;
313+
}
289314
}
290315
}
291316

@@ -297,7 +322,9 @@ int load_pixmaps_from_image()
297322
int delay;
298323
const char *err;
299324
GifFileType *gif = NULL;
325+
size_t canvas_size;
300326
DATA32 *canvas = NULL;
327+
DATA32 *old_canvas = NULL;
301328
Imlib_Image img, img_scaled;
302329
Pixmap pmap;
303330
GraphicsControlBlock gcb;
@@ -313,21 +340,22 @@ int load_pixmaps_from_image()
313340
Background_anim.frames = malloc(sizeof(struct Background_frame)
314341
* gif->ImageCount);
315342

316-
canvas = malloc(sizeof(DATA32) * gif->SWidth * gif->SHeight);
343+
canvas_size = sizeof(DATA32) * gif->SWidth * gif->SHeight;
344+
canvas = malloc(canvas_size);
345+
old_canvas = malloc(canvas_size);
317346

318347
/* Render each image */
319348
for(int i = 0; i < gif->ImageCount; ++i) {
320349
desc = gif->SavedImages[i].ImageDesc;
321-
322-
/* Render image on canvas */
323350
DGifSavedExtensionToGCB(gif, i, &gcb);
324-
render_image(gif, &gcb, &gif->SavedImages[i], canvas, &color_total);
325-
326-
//TODO: detect invald gif values, eg gcb delay
327351
pmap = XCreatePixmap(display, root, root_attr.width,
328352
root_attr.height, root_attr.depth);
329353
XSync(display, false);
330354

355+
/* Render image on canvas */
356+
render_image(gif, &gcb, &gif->SavedImages[i], canvas, &color_total);
357+
358+
331359
/* Render canvas on pixmap with imlib2 */
332360
img = imlib_create_image_using_data(gif->SWidth,
333361
gif->SHeight,
@@ -350,6 +378,10 @@ int load_pixmaps_from_image()
350378
imlib_context_set_image(img);
351379
imlib_free_image();
352380

381+
/* Dispose image */
382+
dispose_image(gif, &gcb, &gif->SavedImages[i], canvas, old_canvas);
383+
memcpy(old_canvas, canvas, canvas_size);
384+
353385
delay = (gcb.DelayTime) ? gcb.DelayTime : 1; // Min delay time
354386
Background_anim.frames[i].p = pmap;
355387
Background_anim.frames[((i==0) ? gif->ImageCount : i)-1].dur

0 commit comments

Comments
 (0)