Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

249 lines
5.4 KiB

  1. /******************************Module*Header*******************************\
  2. * Module Name: ssa8.c
  3. *
  4. * Operations on .a8 files
  5. *
  6. * Copyright (c) 1995 Microsoft Corporation
  7. *
  8. \**************************************************************************/
  9. #include <windows.h>
  10. #include <stdio.h>
  11. #include <string.h>
  12. #include <stdlib.h>
  13. #include "tk.h"
  14. #include "sscommon.h"
  15. #define ESCAPE 0
  16. #define ESC_ENDLINE 0
  17. #define ESC_ENDBITMAP 1
  18. #define ESC_DELTA 2
  19. #define ESC_RANDOM 3
  20. #define RANDOM_COUNT(c) ((c)-(ESC_RANDOM-1))
  21. #define COUNT_SIZE 256
  22. #define MAXRUN (COUNT_SIZE-1)
  23. #define MAXRND (RANDOM_COUNT(COUNT_SIZE)-1)
  24. typedef unsigned char *HwMem;
  25. typedef unsigned long HwMemSize;
  26. #define HW_UNALIGNED UNALIGNED
  27. static HwMemSize HwuRld(HwMem src, HwMem dest, HwMemSize stride)
  28. {
  29. unsigned short code;
  30. unsigned char run, esc;
  31. size_t len;
  32. HwMem s;
  33. HwMem f;
  34. s = src;
  35. f = dest;
  36. for (;;)
  37. {
  38. code = *((unsigned short HW_UNALIGNED *)s)++;
  39. run = code & 0xff;
  40. esc = code >> 8;
  41. if (run == ESCAPE)
  42. {
  43. if (esc == ESC_ENDBITMAP)
  44. {
  45. break;
  46. }
  47. else if (esc == ESC_DELTA)
  48. {
  49. len = *((unsigned short HW_UNALIGNED *)s)++;
  50. while (len-- > 0)
  51. {
  52. *f = 0;
  53. f += stride;
  54. }
  55. }
  56. else if (esc >= ESC_RANDOM)
  57. {
  58. len = RANDOM_COUNT(esc);
  59. while (len-- > 0)
  60. {
  61. *f = *s++;
  62. f += stride;
  63. }
  64. }
  65. }
  66. else
  67. {
  68. while (run-- > 0)
  69. {
  70. *f = esc;
  71. f += stride;
  72. }
  73. }
  74. }
  75. return (HwMemSize)((ULONG_PTR)(s-src));
  76. }
  77. static HwMemSize HwuRldTo32(HwMem src, HwMem dest, HwMemSize stride,
  78. DWORD *translate)
  79. {
  80. unsigned short code;
  81. unsigned char run, esc;
  82. size_t len;
  83. HwMem s;
  84. DWORD *f, tran;
  85. s = src;
  86. f = (DWORD *)dest;
  87. for (;;)
  88. {
  89. code = *((unsigned short HW_UNALIGNED *)s)++;
  90. run = code & 0xff;
  91. esc = code >> 8;
  92. if (run == ESCAPE)
  93. {
  94. if (esc == ESC_ENDBITMAP)
  95. {
  96. break;
  97. }
  98. else if (esc == ESC_DELTA)
  99. {
  100. len = *((unsigned short HW_UNALIGNED *)s)++;
  101. while (len-- > 0)
  102. {
  103. *f = translate[0];
  104. f += stride;
  105. }
  106. }
  107. else if (esc >= ESC_RANDOM)
  108. {
  109. len = RANDOM_COUNT(esc);
  110. while (len-- > 0)
  111. {
  112. *f = translate[*s++];
  113. f += stride;
  114. }
  115. }
  116. }
  117. else
  118. {
  119. tran = translate[esc];
  120. while (run-- > 0)
  121. {
  122. *f = tran;
  123. f += stride;
  124. }
  125. }
  126. }
  127. return (HwMemSize)((ULONG_PTR)(s-src));
  128. }
  129. #define ALPHA_SIGNATURE 0xa0a1a2a3
  130. #define COMPRESS_NONE 0
  131. #define COMPRESS_RLE 1
  132. BOOL ss_A8ImageLoad(void *pvResource, TEXTURE *ptex)
  133. {
  134. DWORD compress;
  135. DWORD size;
  136. DWORD *pal;
  137. BYTE *buf;
  138. DWORD *pdwA8;
  139. pdwA8 = (DWORD *)pvResource;
  140. // Check data signature for alpha texture format
  141. if (*pdwA8 != ALPHA_SIGNATURE)
  142. {
  143. return FALSE;
  144. }
  145. pdwA8++;
  146. ptex->width = *pdwA8++;
  147. ptex->height = *pdwA8++;
  148. // Make sure depth is 8bpp
  149. if (*pdwA8 != 8)
  150. {
  151. return FALSE;
  152. }
  153. pdwA8++;
  154. size = ptex->width*ptex->height;
  155. // Compression type
  156. compress = *pdwA8++;
  157. // Compressed data size only if compressed, not used
  158. pdwA8++;
  159. // Remember pointer to palette data
  160. pal = pdwA8;
  161. pdwA8 += 256;
  162. if (ss_PalettedTextureEnabled())
  163. {
  164. // Allocate data for final image
  165. ptex->data = malloc(size);
  166. if (ptex->data == NULL)
  167. {
  168. return FALSE;
  169. }
  170. ptex->pal_size = 256;
  171. ptex->pal = malloc(ptex->pal_size*sizeof(RGBQUAD));
  172. if (ptex->pal == NULL)
  173. {
  174. free(ptex->data);
  175. return FALSE;
  176. }
  177. memcpy(ptex->pal, pal, ptex->pal_size*sizeof(RGBQUAD));
  178. // Unpack 8bpp data into final image
  179. if (compress == COMPRESS_NONE)
  180. {
  181. memcpy(ptex->data, pdwA8, size);
  182. }
  183. else
  184. {
  185. HwuRld((HwMem)pdwA8, ptex->data, 1);
  186. }
  187. ptex->format = GL_COLOR_INDEX;
  188. ptex->components = GL_COLOR_INDEX8_EXT;
  189. }
  190. else
  191. {
  192. // Allocate data for final image
  193. ptex->data = malloc(size*sizeof(DWORD));
  194. if (ptex->data == NULL)
  195. {
  196. return FALSE;
  197. }
  198. ptex->pal_size = 0;
  199. ptex->pal = NULL;
  200. // Unpack 8bpp data into final image
  201. if (compress == COMPRESS_NONE)
  202. {
  203. DWORD i;
  204. BYTE *src;
  205. DWORD *dst;
  206. src = (BYTE *)pdwA8;
  207. dst = (DWORD *)ptex->data;
  208. for (i = 0; i < size; i++)
  209. {
  210. *dst++ = pal[*src++];
  211. }
  212. }
  213. else
  214. {
  215. HwuRldTo32((HwMem)pdwA8, ptex->data, 1, pal);
  216. }
  217. ptex->format = GL_BGRA_EXT;
  218. ptex->components = 4;
  219. }
  220. return TRUE;
  221. }