diff --git a/src/m_anigif.c b/src/m_anigif.c
index 8113e20d8dd4231d606d8e986d5f025684e1bc11..7c2bb359e081645e6ded76ec1a0f2b4b140f60e2 100644
--- a/src/m_anigif.c
+++ b/src/m_anigif.c
@@ -499,20 +499,22 @@ static size_t gifframe_size = 8192;
 // converts an RGB frame to a frame with a palette.
 //
 #ifdef HWRENDER
+static colorlookup_t gif_colorlookup;
+
 static void GIF_rgbconvert(UINT8 *linear, UINT8 *scr)
 {
 	UINT8 r, g, b;
 	size_t src = 0, dest = 0;
 	size_t size = (vid.width * vid.height * 3);
 
-	InitColorLUT(gif_framepalette, true);
+	InitColorLUT(&gif_colorlookup, gif_framepalette, true);
 
 	while (src < size)
 	{
 		r = (UINT8)linear[src];
 		g = (UINT8)linear[src + 1];
 		b = (UINT8)linear[src + 2];
-		scr[dest] = GetColorLUTDirect(r, g, b);
+		scr[dest] = GetColorLUTDirect(&gif_colorlookup, r, g, b);
 		src += (3 * scrbuf_downscaleamt);
 		dest += scrbuf_downscaleamt;
 	}
diff --git a/src/r_picformats.c b/src/r_picformats.c
index 39aaeef649f879ef507771e9f25652fed875c188..dbd090fc719f092ea9e1d03fd2773c698211fd48 100644
--- a/src/r_picformats.c
+++ b/src/r_picformats.c
@@ -52,6 +52,10 @@
 
 static unsigned char imgbuf[1<<26];
 
+#ifdef PICTURE_PNG_USELOOKUP
+static colorlookup_t png_colorlookup;
+#endif
+
 /** Converts a picture between two formats.
   *
   * \param informat Input picture format.
@@ -964,6 +968,11 @@ void *Picture_PNGConvert(
 	if (outbpp == PICDEPTH_8BPP)
 		memset(flat, TRANSPARENTPIXEL, (width * height));
 
+#ifdef PICTURE_PNG_USELOOKUP
+	if (outbpp != PICDEPTH_32BPP)
+		InitColorLUT(&png_colorlookup, pMasterPalette, false);
+#endif
+
 	for (y = 0; y < height; y++)
 	{
 		png_bytep row = row_pointers[y];
@@ -988,7 +997,11 @@ void *Picture_PNGConvert(
 				}
 				else
 				{
+#ifdef PICTURE_PNG_USELOOKUP
+					UINT8 palidx = GetColorLUT(&png_colorlookup, red, green, blue);
+#else
 					UINT8 palidx = NearestColor(red, green, blue);
+#endif
 					if (outbpp == PICDEPTH_16BPP)
 					{
 						UINT16 *outflat = (UINT16 *)flat;
diff --git a/src/r_picformats.h b/src/r_picformats.h
index 58c84b2c8189195d53ade22720026c02df611092..32754d64ea9048fa759f6fed309ba2d511b2e798 100644
--- a/src/r_picformats.h
+++ b/src/r_picformats.h
@@ -113,6 +113,8 @@ void *Picture_PNGConvert(
 boolean Picture_PNGDimensions(UINT8 *png, INT16 *width, INT16 *height, size_t size);
 #endif
 
+#define PICTURE_PNG_USELOOKUP
+
 // SpriteInfo
 extern spriteinfo_t spriteinfo[NUMSPRITES];
 void R_LoadSpriteInfoLumps(UINT16 wadnum, UINT16 numlumps);
diff --git a/src/v_video.c b/src/v_video.c
index 3ac694dd45c417ffb344d2f417779b54d5331f33..26403b520964b0a73e202f867d0cf70441efb6c5 100644
--- a/src/v_video.c
+++ b/src/v_video.c
@@ -3667,21 +3667,19 @@ Unoptimized version
 }
 
 // Generates a RGB565 color look-up table
-static colorlookup_t colorlookup;
-
-void InitColorLUT(RGBA_t *palette, boolean makecolors)
+void InitColorLUT(colorlookup_t *lut, RGBA_t *palette, boolean makecolors)
 {
 	size_t palsize = (sizeof(RGBA_t) * 256);
 
-	if (!colorlookup.init || memcmp(colorlookup.palette, palette, palsize))
+	if (!lut->init || memcmp(lut->palette, palette, palsize))
 	{
 		INT32 i;
 
-		colorlookup.init = true;
-		memcpy(colorlookup.palette, palette, palsize);
+		lut->init = true;
+		memcpy(lut->palette, palette, palsize);
 
 		for (i = 0; i < 0xFFFF; i++)
-			colorlookup.table[i] = 0xFFFF;
+			lut->table[i] = 0xFFFF;
 
 		if (makecolors)
 		{
@@ -3692,25 +3690,25 @@ void InitColorLUT(RGBA_t *palette, boolean makecolors)
 			for (b = 0; b < 0xFF; b++)
 			{
 				i = CLUTINDEX(r, g, b);
-				if (colorlookup.table[i] == 0xFFFF)
-					colorlookup.table[i] = NearestPaletteColor(r, g, b, palette);
+				if (lut->table[i] == 0xFFFF)
+					lut->table[i] = NearestPaletteColor(r, g, b, palette);
 			}
 		}
 	}
 }
 
-UINT8 GetColorLUT(UINT8 r, UINT8 g, UINT8 b)
+UINT8 GetColorLUT(colorlookup_t *lut, UINT8 r, UINT8 g, UINT8 b)
 {
 	INT32 i = CLUTINDEX(r, g, b);
-	if (colorlookup.table[i] == 0xFFFF)
-		colorlookup.table[i] = NearestPaletteColor(r << 3, g << 2, b << 3, colorlookup.palette);
-	return colorlookup.table[i];
+	if (lut->table[i] == 0xFFFF)
+		lut->table[i] = NearestPaletteColor(r, g, b, lut->palette);
+	return lut->table[i];
 }
 
-UINT8 GetColorLUTDirect(UINT8 r, UINT8 g, UINT8 b)
+UINT8 GetColorLUTDirect(colorlookup_t *lut, UINT8 r, UINT8 g, UINT8 b)
 {
 	INT32 i = CLUTINDEX(r, g, b);
-	return colorlookup.table[i];
+	return lut->table[i];
 }
 
 // V_Init
diff --git a/src/v_video.h b/src/v_video.h
index 6cd10f606c5da51e7b11b5612d7ff039991c9543..a6ca197bb2e6c13783a1a8d245e0bfcf9121fa84 100644
--- a/src/v_video.h
+++ b/src/v_video.h
@@ -40,10 +40,6 @@ void V_Init(void);
 // Color look-up table
 #define CLUTINDEX(r, g, b) (((r) >> 3) << 11) | (((g) >> 2) << 5) | ((b) >> 3)
 
-void InitColorLUT(RGBA_t *palette, boolean makecolors);
-UINT8 GetColorLUT(UINT8 r, UINT8 g, UINT8 b);
-UINT8 GetColorLUTDirect(UINT8 r, UINT8 g, UINT8 b);
-
 typedef struct
 {
 	boolean init;
@@ -51,6 +47,10 @@ typedef struct
 	UINT16 table[0xFFFF];
 } colorlookup_t;
 
+void InitColorLUT(colorlookup_t *lut, RGBA_t *palette, boolean makecolors);
+UINT8 GetColorLUT(colorlookup_t *lut, UINT8 r, UINT8 g, UINT8 b);
+UINT8 GetColorLUTDirect(colorlookup_t *lut, UINT8 r, UINT8 g, UINT8 b);
+
 // Set the current RGB palette lookup to use for palettized graphics
 void V_SetPalette(INT32 palettenum);