Nearest neighbour scaling diff ported to gifplay after MIT-SHM code was added.

diff -r 59d4bf6d7a5a gif.c
--- a/gif.c	Sat May 25 00:11:38 2013 +0200
+++ b/gif.c	Thu May 30 22:45:04 2013 +0200
@@ -1,7 +1,8 @@
 #include "gifplay.h"
 
 static void
-im2rgba(GifFileType *gif, SavedImage *im, rgba palette[256], rgba *buf)
+im2rgba(GifFileType *gif, SavedImage *im, rgba palette[256], rgba *buf,
+        float scale)
 {
 	unsigned x, y, iw = im->ImageDesc.Width, ih = im->ImageDesc.Height,
 		cw = gif->SWidth, ch = gif->SHeight,
@@ -9,15 +10,19 @@
 	rgba col;
 	size_t buf_pos, im_pos;
 
-	for (y = 0; y < MIN(ih,ch); y++) {
-		for (x = 0; x < MIN(iw,cw); x++) {
-			im_pos  = y * iw + x;
-			buf_pos = (y + top) * cw + x + left;
+	int xmax = MIN(cw, iw) * scale;
+	int ymax = MIN(ch, ih) * scale;
 
-			if (x + left > MIN(iw, cw)) {          /* broken gif? */
-				puts("broken"); /* better protect buf bounds. */
-			       	break;
-			}
+	for (y = 0; y < ymax; y++) {
+		for (x = 0; x < xmax; x++) {
+			im_pos  = (int)(y/scale) * iw + (int)(x/scale);
+			//buf_pos = (y + top) * xmax + x + left;
+			buf_pos = (y + (int)(top*scale)) * (int)(cw*scale) + x + (int)(left*scale);
+
+			//if (x + left > MIN(iw, cw)) {          /* broken gif? */
+			//	puts("broken"); /* better protect buf bounds. */
+			//       	break;
+			//}
 
 			col = palette[im->RasterBits[im_pos]];
 			if (!col.channel.a)
@@ -43,7 +48,7 @@
 
 static void
 disposebuf(GifFileType *gif, SavedImage *im, rgba *buf, rgba palette[256],
-	GraphicsControlBlock *GCB)
+	GraphicsControlBlock *GCB, float scale)
 {
 	int w = gif->SWidth, h = gif->SHeight;
 	size_t i; 
@@ -58,7 +63,7 @@
 		break;
 
 	case DISPOSE_BACKGROUND:           /* Change area to background color */
-		for (i = 0; i < w*h; i++)
+		for (i = 0; i < w*h*scale*scale; i++)
 			buf[i].all = gif->SBackGroundColor;
 		break;
 
@@ -82,7 +87,7 @@
 }
 
 int
-gif2rgba(GifFileType *gif, int frame, rgba *data)
+gif2rgba(GifFileType *gif, int frame, rgba *data, float scale)
 {
 	/* data contains the previous frame. Used depending on disposal mode */
 	SavedImage *frm = &gif->SavedImages[frame];
@@ -95,9 +100,9 @@
 	DGifSavedExtensionToGCB(gif, frame, &GCB);
 
 	cmap2rgba(cmap, palette, GCB.TransparentColor);
-	disposebuf(gif, frm, data, palette, &GCB);
+	disposebuf(gif, frm, data, palette, &GCB, scale);
 
-	im2rgba(gif, frm, palette, data);
+	im2rgba(gif, frm, palette, data, scale);
 
 	return GCB.DelayTime;
 }
diff -r 59d4bf6d7a5a gifplay.h
--- a/gifplay.h	Sat May 25 00:11:38 2013 +0200
+++ b/gifplay.h	Thu May 30 22:45:04 2013 +0200
@@ -39,6 +39,7 @@
 extern int reverse;
 extern int expand;
 extern float sfact;
+extern int expand;
 int main(int, char**);
 void play(char *);
 
@@ -50,6 +51,6 @@
 void draw(GifFileType *);
 
 /* gif.c */
-int gif2rgba(GifFileType *gif, int frame, rgba *data); /* returns delay */
+int gif2rgba(GifFileType *gif, int frame, rgba *data, float scale); /* returns delay */
 
 #endif
diff -r 59d4bf6d7a5a main.c
--- a/main.c	Sat May 25 00:11:38 2013 +0200
+++ b/main.c	Thu May 30 22:45:04 2013 +0200
@@ -89,8 +89,6 @@
 {
 	int err;
 	GifFileType *gif;
-	size_t buf_size;
-	rgba *buf;
 
 	if ((gif = DGifOpenFileName(fname, &err)) == NULL) {
 		print_gif_error(fname, err);
diff -r 59d4bf6d7a5a x11.c
--- a/x11.c	Sat May 25 00:11:38 2013 +0200
+++ b/x11.c	Thu May 30 22:45:04 2013 +0200
@@ -27,6 +27,9 @@
 static XShmSegmentInfo shminfo;
 #endif /* WITH_MIT_SHM */
 
+static float scale;
+static int x_offset = 0, y_offset = 0;
+
 static void nextimg();
 static void previmg();
 static void nextframe();
@@ -132,7 +135,7 @@
 	int delay;
 
 	if (lastupdate != cur_img) {
-		delay = gif2rgba(gif, cur_img, buf);
+		delay = gif2rgba(gif, cur_img, buf, scale);
 		lastupdate = cur_img;
 		put();
 		settimer(delay); /* firing timers in update instead of the
@@ -161,18 +164,19 @@
 static inline void
 makeimg(void)
 {
+	size_t buf_size = sizeof(rgba) * gif->SWidth * gif->SHeight * scale * scale;
+	
 #ifdef WITH_MIT_SHM
 	if (!(haveshm = XShmQueryExtension(dpy))) {
 		fputs("Warning: X11 MIT-SHM extension is not available.\n",stderr);
 	} else {
-		shminfo.shmid = shmget(IPC_PRIVATE,
-			sizeof(rgba) * gif->SWidth * gif->SHeight, IPC_CREAT|0777);
+		shminfo.shmid = shmget(IPC_PRIVATE, buf_size, IPC_CREAT|0777);
 
 		haveshm = shminfo.shmid != -1 && XShmAttach(dpy, &shminfo);
 
 		if (haveshm) {
 			img = XShmCreateImage(dpy, visual, 24, ZPixmap, NULL, 
-				&shminfo, gif->SWidth, gif->SHeight);
+				&shminfo, gif->SWidth * scale, gif->SHeight * scale);
 			buf = shmat(shminfo.shmid, 0, 0);
 			img->data = shminfo.shmaddr = (char*)buf;
 			shminfo.readOnly = False;
@@ -185,11 +189,11 @@
 		}
 	}
 #endif /* WITH_MIT_SHM */
-	if (!(buf = malloc(sizeof(rgba) * gif->SWidth * gif->SHeight)))
+	if (!(buf = malloc(buf_size)))
 		perror("malloc"), exit(1);
 	
 	img = XCreateImage(dpy, visual, 24, ZPixmap, 0, NULL,
-		gif->SWidth, gif->SHeight, 32, 0);
+		gif->SWidth * scale, gif->SHeight * scale, 32, 0);
 	img->data = (char*)buf;
 }
 
@@ -280,6 +284,7 @@
 	/* initialiser function for mainloop() */
 	unsigned w, h;
 	int s, x = 10, y = 10;
+	float wscale, hscale;
 	
 	gif = thegif;
 	w = gif->SWidth, h = gif->SHeight;
@@ -296,8 +301,21 @@
 
 	XParseGeometry(geom, &x, &y, &w, &h);
 
+	if(expand) {
+		wscale = (float)w / (float)gif->SWidth;
+		hscale = (float)h / (float)gif->SHeight;
+		scale = MIN(wscale, hscale);
+	} else {
+		scale = 1;
+	}
+
+	if(w > gif->SWidth * scale)
+		x_offset = (w - gif->SWidth * scale) / 2;
+	if(h > gif->SHeight * scale)
+		y_offset = (h - gif->SHeight * scale) / 2;
+
 	win = XCreateSimpleWindow(dpy, DefaultRootWindow(dpy), x, y, w, h, 0,
-			BlackPixel(dpy, s), WhitePixel(dpy, s));
+			BlackPixel(dpy, s), BlackPixel(dpy, s));
 
 	XStoreName(dpy, win, "gifplay");
 
