From aa853f8b78d17f616a82768c19dcfdd84003ddde Mon Sep 17 00:00:00 2001
From: Marcus Comstedt <marcus@mc.pp.se>
Date: Sun, 27 Feb 2000 15:48:13 +0100
Subject: [PATCH] Basic encoding implemented.

Rev: src/modules/Image/encodings/pvr.c:1.5
---
 src/modules/Image/encodings/pvr.c | 105 ++++++++++++++++++++++++++++--
 1 file changed, 101 insertions(+), 4 deletions(-)

diff --git a/src/modules/Image/encodings/pvr.c b/src/modules/Image/encodings/pvr.c
index 79345b6855..702b11ba39 100644
--- a/src/modules/Image/encodings/pvr.c
+++ b/src/modules/Image/encodings/pvr.c
@@ -4,7 +4,7 @@
 #include <ctype.h>
 
 #include "stralloc.h"
-RCSID("$Id: pvr.c,v 1.4 2000/02/27 14:01:31 marcus Exp $");
+RCSID("$Id: pvr.c,v 1.5 2000/02/27 14:48:13 marcus Exp $");
 #include "pike_macros.h"
 #include "object.h"
 #include "constants.h"
@@ -15,6 +15,7 @@ RCSID("$Id: pvr.c,v 1.4 2000/02/27 14:01:31 marcus Exp $");
 #include "mapping.h"
 #include "error.h"
 #include "operators.h"
+#include "stralloc.h"
 #include "builtin_functions.h"
 #include "module_support.h"
 
@@ -63,6 +64,7 @@ extern struct program *image_program;
 **!	options is a mapping with optional values:
 **!	<pre>
 **!	   "alpha":object            - alpha channel
+**!	   "global_index":int	     - global index
 **!	</pre>
 */
 
@@ -98,9 +100,104 @@ static void init_twiddletab()
   twiddleinited=1;
 }
 
+static void pvr_encode_rect(INT32 attr, rgb_group *src, unsigned char *dst,
+			    INT32 stride, unsigned int h, unsigned int w)
+{
+  INT32 cnt = h * w;
+  switch(attr&0xff) {
+   case MODE_RGB565:
+     while(cnt--) {
+       unsigned int p =
+	 ((src->r&0xf8)<<8)|((src->g&0xfc)<<3)|((src->b&0xf8)>>3);
+       *dst++=p&0xff;
+       *dst++=(p&0xff00)>>8;
+       src++;
+     }
+     break;
+  }
+}
+
 void image_pvr_f_encode(INT32 args)
 {
-   error("not implemented\n");
+  struct object *imgo;
+  struct mapping *optm = NULL;
+  struct image *alpha = NULL, *img;
+  INT32 gbix, sz, attr;
+  int has_gbix=0;
+  struct pike_string *res;
+  unsigned char *dst;
+
+  get_all_args("Image.PVR.encode", args, (args>1 && !IS_ZERO(&sp[1-args])?
+					  "%o%m":"%o"), &imgo, &optm);
+
+  if((img=(struct image*)get_storage(imgo, image_program))==NULL)
+    error("Image.PVR.encode: illegal argument 1\n");
+
+  if(optm != NULL) {
+    struct svalue *s;
+    if((s = simple_mapping_string_lookup(optm, "alpha"))!=NULL && !IS_ZERO(s))
+      if(s->type != T_OBJECT ||
+	 (alpha=(struct image*)get_storage(s->u.object, image_program))==NULL)
+	error("Image.PVR.encode: option (arg 2) \"alpha\" has illegal type\n");
+    if((s = simple_mapping_string_lookup(optm, "global_index"))!=NULL &&
+       !IS_UNDEFINED(s))
+      if(s->type == T_INT) {
+	gbix = s->u.integer;
+	has_gbix=1;
+      }
+      else
+	error("Image.PVR.encode: option (arg 2) \"global_index\" has illegal type\n");
+  }
+
+  if (!img->img)
+    error("Image.PVR.encode: no image\n");
+  if (alpha && !alpha->img)
+    error("Image.PVR.encode: no alpha image\n");
+
+  if (alpha && (alpha->xsize != img->xsize || alpha->ysize != img->ysize))
+    error("Image.PVR.encode: alpha and image size differ\n");
+
+  res = begin_shared_string(8+(sz=8+2*img->xsize*img->ysize)+(has_gbix? 12:0));
+  dst = STR0(res);
+
+  attr = MODE_RECTANGLE|MODE_RGB565;
+
+  if(has_gbix) {
+    *dst++ = 'G';
+    *dst++ = 'B';
+    *dst++ = 'I';
+    *dst++ = 'X';
+    *dst++ = 4;
+    *dst++ = 0;
+    *dst++ = 0;
+    *dst++ = 0;
+    *dst++ = (gbix&0x000000ff);
+    *dst++ = (gbix&0x0000ff00)>>8;
+    *dst++ = (gbix&0x00ff0000)>>16;
+    *dst++ = (gbix&0xff000000)>>24;
+  }
+
+  *dst++ = 'P';
+  *dst++ = 'V';
+  *dst++ = 'R';
+  *dst++ = 'T';
+  *dst++ = (sz&0x000000ff);
+  *dst++ = (sz&0x0000ff00)>>8;
+  *dst++ = (sz&0x00ff0000)>>16;
+  *dst++ = (sz&0xff000000)>>24;
+  *dst++ = (attr&0x000000ff);
+  *dst++ = (attr&0x0000ff00)>>8;
+  *dst++ = (attr&0x00ff0000)>>16;
+  *dst++ = (attr&0xff000000)>>24;
+  *dst++ = (img->xsize&0x00ff);
+  *dst++ = (img->xsize&0xff00)>>8;
+  *dst++ = (img->ysize&0x00ff);
+  *dst++ = (img->ysize&0xff00)>>8;
+
+  pvr_encode_rect(attr, img->img, dst, 0, img->ysize, img->xsize);
+
+  pop_n_elems(args);
+  push_string(end_shared_string(res));
 }
 
 static void pvr_decode_rect(INT32 attr, unsigned char *src, rgb_group *dst,
@@ -362,7 +459,7 @@ void img_pvr_decode(INT32 args,int header_only)
 	error("unknown PVR color mode\n");
      }
 
-     if(mipmap)
+     if(mipmap) /* Just skip everything except the largest version */
        for(x=w; x>>=1;)
 	 mipmap += x*x;
 
@@ -454,7 +551,7 @@ void init_image_pvr()
   ADD_FUNCTION( "decode",  image_pvr_f_decode,  tFunc(tStr,tObj), 0);
   ADD_FUNCTION( "decode_alpha",  image_pvr_f_decode_alpha,  tFunc(tStr,tObj), 0);
   ADD_FUNCTION( "_decode", image_pvr_f__decode, tFunc(tStr,tMapping), 0);
-  ADD_FUNCTION( "encode",  image_pvr_f_encode,  tFunc(tStr,tObj), 0);
+  ADD_FUNCTION( "encode",  image_pvr_f_encode,  tFunc(tObj tOr(tVoid,tMapping),tStr), 0);
   ADD_FUNCTION( "decode_header", image_pvr_f_decode_header, tFunc(tStr,tMapping), 0);
 }
 
-- 
GitLab