rnd-20060430-1-src
[rocksndiamonds.git] / src / libgame / image.c
index 4088af3b0bf5665b171efee4e64ffa4decd5cb7d..cb8de4c87ed46ab8397a46f8f6a852843cb3344b 100644 (file)
@@ -31,13 +31,6 @@ Image *newImage(unsigned int width, unsigned int height, unsigned int depth)
   unsigned int bytes_per_pixel = (depth + 7) / 8;
   int i;
 
-#if 0
-  if (depth > 8)
-    Error(ERR_EXIT, "images with more than 256 colors are not supported");
-
-  depth = 8;
-#endif
-
   image = checked_calloc(sizeof(Image));
   image->data = checked_calloc(width * height * bytes_per_pixel);
   image->width = width;
@@ -636,6 +629,8 @@ XImageInfo *Image_to_Pixmap(Display *display, int screen, Visual *visual,
 
   Important note: The scaling code currently only supports scaling of the image
   up or down by a power of 2 -- other scaling factors currently not supported!
+  Also not supported is scaling of pixmap masks (with depth 1); to scale them,
+  better use Pixmap_to_Mask() for now.
   -----------------------------------------------------------------------------
 */
 
@@ -648,13 +643,9 @@ void ZoomPixmap(Display *display, GC gc, Pixmap src_pixmap, Pixmap dst_pixmap,
   int bits_per_pixel;
   int bytes_per_pixel;
   int x, y, xx, yy, i;
-#if 1
-  boolean scale_down = (src_width > dst_width);
-  int zoom_factor;
-#else
-  int zoom_factor = src_width / dst_width;     /* currently very limited! */
-#endif
   int row_skip, col_skip;
+  int zoom_factor;
+  boolean scale_down = (src_width > dst_width);
 
   if (scale_down)
   {
@@ -706,33 +697,6 @@ void ZoomPixmap(Display *display, GC gc, Pixmap src_pixmap, Pixmap dst_pixmap,
   {
     row_skip = src_width * bytes_per_pixel;
 
-#if 0
-    printf("::: %d, %d -> %d, %d [%d / %d]\n[%ld -> %ld (%ld)] [%ld -> %ld (%ld)]\n",
-          src_width, src_height,
-          dst_width, dst_height,
-          zoom_factor, bytes_per_pixel,
-          src_ptr,
-          src_ptr + src_width * src_height * bytes_per_pixel,
-          src_width * src_height * bytes_per_pixel,
-          dst_ptr,
-          dst_ptr + dst_width * dst_height * bytes_per_pixel,
-          dst_width * dst_height * bytes_per_pixel);
-
-    printf("A\n");
-
-    for (i = 0; i < src_width * src_height * bytes_per_pixel;
-        i++)
-    {
-      byte x = *(byte *)(src_ptr + i);
-
-      printf("::: %d ...\n", i);
-
-      x = x * 1;
-    }
-
-    printf("B\n");
-#endif
-
     /* scale image up by scaling factor 'zoom_factor' */
     for (y = 0; y < src_height; y++)
     {
@@ -741,21 +705,13 @@ void ZoomPixmap(Display *display, GC gc, Pixmap src_pixmap, Pixmap dst_pixmap,
        if (yy > 0)
          src_ptr -= row_skip;
 
-#if 0
-       printf("::: [%d -> %ld / %ld]\n", y, src_ptr, dst_ptr);
-#endif
-
        for (x = 0; x < src_width; x++)
        {
          for (xx = 0; xx < zoom_factor; xx++)
            for (i = 0; i < bytes_per_pixel; i++)
-#if 1
              *dst_ptr++ = *(src_ptr + i);
-#else
-             *dst_ptr++ = 0;
-#endif
 
-         src_ptr += i;
+         src_ptr += bytes_per_pixel;
        }
       }
     }
@@ -857,7 +813,12 @@ struct ImageInfo
   int num_references;
 
   Bitmap *bitmap;
-  boolean contains_small_images;
+
+  int original_width;                  /* original image file width */
+  int original_height;                 /* original image file height */
+
+  boolean contains_small_images;       /* set after adding small images */
+  boolean scaled_up;                   /* set after scaling up */
 };
 typedef struct ImageInfo ImageInfo;
 
@@ -868,7 +829,7 @@ static void *Load_PCX(char *filename)
   ImageInfo *img_info;
 
 #if 0
-  printf("loading PCX file '%s'\n", filename);
+  printf("::: loading PCX file '%s'\n", filename);
 #endif
 
   img_info = checked_calloc(sizeof(ImageInfo));
@@ -883,7 +844,11 @@ static void *Load_PCX(char *filename)
 
   img_info->source_filename = getStringCopy(filename);
 
+  img_info->original_width  = img_info->bitmap->width;
+  img_info->original_height = img_info->bitmap->height;
+
   img_info->contains_small_images = FALSE;
+  img_info->scaled_up = FALSE;
 
   return img_info;
 }
@@ -910,7 +875,7 @@ int getImageListSize()
          image_info->num_dynamic_file_list_entries);
 }
 
-struct FileInfo *getImageListEntry(int pos)
+struct FileInfo *getImageListEntryFromImageID(int pos)
 {
   int num_list_entries = image_info->num_file_list_entries;
   int list_pos = (pos < num_list_entries ? pos : pos - num_list_entries);
@@ -932,33 +897,30 @@ static ImageInfo *getImageInfoEntryFromImageID(int pos)
 
 Bitmap *getBitmapFromImageID(int pos)
 {
-#if 0
-  int num_list_entries = image_info->num_file_list_entries;
-  int list_pos = (pos < num_list_entries ? pos : pos - num_list_entries);
-  ImageInfo **img_info =
-    (ImageInfo **)(pos < num_list_entries ? image_info->artwork_list :
-                  image_info->dynamic_artwork_list);
-
-  return (img_info[list_pos] != NULL ? img_info[list_pos]->bitmap : NULL);
-#else
   ImageInfo *img_info = getImageInfoEntryFromImageID(pos);
 
   return (img_info != NULL ? img_info->bitmap : NULL);
-#endif
 }
 
-char *getTokenFromImageID(int graphic)
+int getOriginalImageWidthFromImageID(int pos)
 {
-#if 0
-  /* !!! this does not work for dynamic artwork (crash!) !!! */
-  struct FileInfo *file_list = (struct FileInfo *)image_info->file_list;
+  ImageInfo *img_info = getImageInfoEntryFromImageID(pos);
+
+  return (img_info != NULL ? img_info->original_width : 0);
+}
 
-  return file_list[graphic].token;
-#else
-  struct FileInfo *file_list = getImageListEntry(graphic);
+int getOriginalImageHeightFromImageID(int pos)
+{
+  ImageInfo *img_info = getImageInfoEntryFromImageID(pos);
+
+  return (img_info != NULL ? img_info->original_height : 0);
+}
+
+char *getTokenFromImageID(int graphic)
+{
+  struct FileInfo *file_list = getImageListEntryFromImageID(graphic);
 
   return (file_list != NULL ? file_list->token : NULL);
-#endif
 }
 
 int getImageIDFromToken(char *token)
@@ -968,7 +930,7 @@ int getImageIDFromToken(char *token)
   int i;
 
   for (i = 0; i < num_list_entries; i++)
-    if (strcmp(file_list[i].token, token) == 0)
+    if (strEqual(file_list[i].token, token))
       return i;
 
   return -1;
@@ -1067,27 +1029,37 @@ void InitImageList(struct ConfigInfo *config_list, int num_file_list_entries,
 void ReloadCustomImages()
 {
 #if 0
-  printf("DEBUG: reloading images '%s' ...\n", artwork.gfx_current_identifier);
+  printf("::: reloading images '%s' ...\n", artwork.gfx_current_identifier);
 #endif
 
   LoadArtworkConfig(image_info);
   ReloadCustomArtworkList(image_info);
 }
 
-void CreateImageWithSmallImages(int pos)
+void CreateImageWithSmallImages(int pos, int zoom_factor)
 {
   ImageInfo *img_info = getImageInfoEntryFromImageID(pos);
 
   if (img_info == NULL || img_info->contains_small_images)
     return;
 
-  CreateBitmapWithSmallBitmaps(img_info->bitmap);
+  CreateBitmapWithSmallBitmaps(img_info->bitmap, zoom_factor);
 
   img_info->contains_small_images = TRUE;
+  img_info->scaled_up = TRUE;
+}
 
-#if 0
-  printf("CreateImageWithSmallImages: '%s' done\n", img_info->source_filename);
-#endif
+void ScaleImage(int pos, int zoom_factor)
+{
+  ImageInfo *img_info = getImageInfoEntryFromImageID(pos);
+
+  if (img_info == NULL || img_info->scaled_up)
+    return;
+
+  if (zoom_factor != 1)
+    ScaleBitmap(img_info->bitmap, zoom_factor);
+
+  img_info->scaled_up = TRUE;
 }
 
 void FreeAllImages()