diff -rupN postgis-old/raster/rt_pg/rtpostgis.sql.in.c postgis-new/raster/rt_pg/rtpostgis.sql.in.c
--- postgis-old/raster/rt_pg/rtpostgis.sql.in.c	2011-04-22 16:23:21.000000000 -0700
+++ postgis-new/raster/rt_pg/rtpostgis.sql.in.c	2011-04-22 16:24:23.000000000 -0700
@@ -578,6 +578,92 @@ CREATE OR REPLACE FUNCTION st_astiff(ras
 	$$ LANGUAGE 'plpgsql' IMMUTABLE STRICT;
 
 -----------------------------------------------------------------------
+-- ST_AsJPEG
+-----------------------------------------------------------------------
+-- Cannot be strict as "options" can be NULL
+CREATE OR REPLACE FUNCTION st_asjpeg(rast raster, options text[])
+	RETURNS bytea
+	AS $$
+	DECLARE
+		num_bands int;
+		i int;
+	BEGIN
+		num_bands := st_numbands($1);
+
+		-- JPEG only supports 8BUI pixeltype
+		FOR i IN 1..num_bands LOOP
+			IF st_bandpixeltype(rast, i) != '8BUI' THEN
+				RAISE EXCEPTION 'The pixel type of band % in the raster is not 8BUI.  The JPEG format can only be used with the 8BUI pixel type.', i;
+			END IF;
+		END LOOP;
+
+		-- JPEG only allows 1 or 3 bands
+		-- we only use the first
+		IF num_bands > 3 THEN
+			RAISE WARNING 'The JPEG format only permits one or three bands.  The first three bands will be used.';
+			rast := st_band(rast, ARRAY[1, 2, 3]);
+			num_bands := st_numbands(rast);
+		ELSEIF num_bands > 1 THEN
+			RAISE WARNING 'The JPEG format only permits one or three bands.  The first band will be used.';
+			rast := st_band(rast, ARRAY[1]);
+			num_bands := st_numbands(rast);
+		END IF;
+
+		RETURN st_asgdalraster($1, 'JPEG', $2, NULL);
+	END;
+	$$ LANGUAGE 'plpgsql' IMMUTABLE;
+
+CREATE OR REPLACE FUNCTION st_asjpeg(rast raster)
+	RETURNS bytea
+	AS $$ SELECT st_asjpeg($1, NULL::text[]) $$
+	LANGUAGE 'SQL' IMMUTABLE STRICT;
+
+CREATE OR REPLACE FUNCTION st_asjpeg(rast raster, nbands int[], options text[])
+	RETURNS bytea
+	AS $$ SELECT st_asjpeg(st_band($1, $2), $3) $$
+	LANGUAGE 'SQL' IMMUTABLE STRICT;
+
+CREATE OR REPLACE FUNCTION st_asjpeg(rast raster, nbands int[])
+	RETURNS bytea
+	AS $$ SELECT st_asjpeg(st_band($1, $2), NULL::text[]) $$
+	LANGUAGE 'SQL' IMMUTABLE STRICT;
+
+CREATE OR REPLACE FUNCTION st_asjpeg(rast raster, nband int)
+	RETURNS bytea
+	AS $$ SELECT st_asjpeg(st_band($1, $2)) $$
+	LANGUAGE 'SQL' IMMUTABLE STRICT;
+
+CREATE OR REPLACE FUNCTION st_asjpeg(rast raster, nbands int[], quality int)
+	RETURNS bytea
+	AS $$
+	DECLARE
+		options text[];
+	BEGIN
+		IF quality IS NOT NULL THEN
+			IF quality > 100 THEN
+				quality := 100;
+			ELSEIF quality < 10 THEN
+				quality := 10;
+			END IF;
+
+			options := array_append(options, 'QUALITY=' || quality);
+		END IF;
+
+		RETURN st_asjpeg(st_band($1, $2), options);
+	END;
+	$$ LANGUAGE 'plpgsql' IMMUTABLE STRICT;
+
+CREATE OR REPLACE FUNCTION st_asjpeg(rast raster, nband int, options text[])
+	RETURNS bytea
+	AS $$ SELECT st_asjpeg(st_band($1, $2), $3) $$
+	LANGUAGE 'SQL' IMMUTABLE STRICT;
+
+CREATE OR REPLACE FUNCTION st_asjpeg(rast raster, nband int, quality int)
+	RETURNS bytea
+	AS $$ SELECT st_asjpeg($1, ARRAY[$2], $3) $$
+	LANGUAGE 'SQL' IMMUTABLE STRICT;
+
+-----------------------------------------------------------------------
 -- MapAlgebra
 -----------------------------------------------------------------------
 -- This function can not be STRICT, because nodatavalueexpr can be NULL (could be just '' though)
diff -rupN postgis-old/raster/test/regress/Makefile.in postgis-new/raster/test/regress/Makefile.in
--- postgis-old/raster/test/regress/Makefile.in	2011-04-22 16:23:21.000000000 -0700
+++ postgis-new/raster/test/regress/Makefile.in	2011-04-22 16:25:22.000000000 -0700
@@ -45,6 +45,7 @@ TEST_FUNC = \
 	rt_reclass.sql \
 	rt_asgdalraster.sql \
 	rt_astiff.sql \
+	rt_asjpeg.sql \
 	$(NULL)
 
 TEST_PROPS = \
diff -rupN postgis-old/raster/test/regress/rt_asjpeg.sql postgis-new/raster/test/regress/rt_asjpeg.sql
--- postgis-old/raster/test/regress/rt_asjpeg.sql	1969-12-31 16:00:00.000000000 -0800
+++ postgis-new/raster/test/regress/rt_asjpeg.sql	2011-04-22 16:24:50.000000000 -0700
@@ -0,0 +1,81 @@
+SELECT md5(
+	ST_AsJPEG(
+		ST_AddBand(ST_MakeEmptyRaster(200, 200, 10, 10, 2, 2, 0, 0, -1), 1, '8BSI', 123, NULL)
+	)
+);
+SELECT md5(
+	ST_AsJPEG(
+		ST_AddBand(ST_MakeEmptyRaster(200, 200, 10, 10, 2, 2, 0, 0, -1), 1, '8BUI', 123, NULL)
+	)
+);
+SELECT md5(
+	ST_AsJPEG(
+		ST_AddBand(ST_MakeEmptyRaster(200, 200, 10, 10, 2, 2, 0, 0, -1), 1, '8BSI', -123, NULL)
+	)
+);
+SELECT md5(
+	ST_AsJPEG(
+		ST_AddBand(ST_MakeEmptyRaster(200, 200, 10, 10, 2, 2, 0, 0, -1), 1, '8BUI', 254, NULL)
+	)
+);
+SELECT md5(
+	ST_AsJPEG(
+		ST_AddBand(
+			ST_AddBand(
+				ST_AddBand(
+					ST_MakeEmptyRaster(200, 200, 10, 10, 2, 2, 0, 0, -1)
+					, 1, '8BUI', 1, 255
+				)
+				, 2, '8BUI', 11, 0
+			)
+			, 3, '8BUI', 111, 127
+		)
+	)
+);
+SELECT md5(
+	ST_AsJPEG(
+		ST_AddBand(
+			ST_AddBand(
+				ST_AddBand(
+					ST_MakeEmptyRaster(200, 200, 10, 10, 2, 2, 0, 0, -1)
+					, 1, '8BSI', 1, -1
+				)
+				, 2, '8BSI', 11, -1
+			)
+			, 3, '8BSI', 111, -1
+		),
+		ARRAY['QUALITY=90','PROGRESSIVE=ON']
+	)
+);
+SELECT md5(
+	ST_AsJPEG(
+		ST_AddBand(
+			ST_AddBand(
+				ST_AddBand(
+					ST_MakeEmptyRaster(200, 200, 10, 10, 2, 2, 0, 0, -1)
+					, 1, '8BSI', 1, -1
+				)
+				, 2, '8BSI', 11, -1
+			)
+			, 3, '8BSI', 111, -1
+		),
+		ARRAY[3,1],
+		50
+	)
+);
+SELECT md5(
+	ST_AsJPEG(
+		ST_AddBand(
+			ST_AddBand(
+				ST_AddBand(
+					ST_MakeEmptyRaster(200, 200, 10, 10, 2, 2, 0, 0, -1)
+					, 1, '8BSI', 1, -1
+				)
+				, 2, '8BSI', 11, -1
+			)
+			, 3, '8BUI', 111, -1
+		),
+		ARRAY[3],
+		10
+	)
+);
diff -rupN postgis-old/raster/test/regress/rt_asjpeg_expected postgis-new/raster/test/regress/rt_asjpeg_expected
--- postgis-old/raster/test/regress/rt_asjpeg_expected	1969-12-31 16:00:00.000000000 -0800
+++ postgis-new/raster/test/regress/rt_asjpeg_expected	2011-04-22 16:24:50.000000000 -0700
@@ -0,0 +1,9 @@
+ERROR:  The pixel type of band 1 in the raster is not 8BUI.  The JPEG format can only be used with the 8BUI pixel type.
+f0de16a21de438249ec0bbd28eafe63c
+ERROR:  The pixel type of band 1 in the raster is not 8BUI.  The JPEG format can only be used with the 8BUI pixel type.
+83b6012757444ff7786b5e8473e6cea3
+WARNING:  The JPEG format only permits one or three bands.  The first band will be used.
+c6be69047e807df076ec653be790eb25
+ERROR:  The pixel type of band 1 in the raster is not 8BUI.  The JPEG format can only be used with the 8BUI pixel type.
+ERROR:  The pixel type of band 1 in the raster is not 8BUI.  The JPEG format can only be used with the 8BUI pixel type.
+d687ffc7b8dcb3ef05cd4fe99656e45d

