Quake II RTX doxygen  1.0 dev
images.c File Reference
#include "shared/shared.h"
#include "common/common.h"
#include "common/cvar.h"
#include "common/files.h"
#include "refresh/images.h"
#include "format/pcx.h"
#include "format/wal.h"
#include "stb_image.h"
#include "stb_image_write.h"

Go to the source code of this file.

Classes

struct  floodfill_t
 

Macros

#define R_COLORMAP_PCX   "pics/colormap.pcx"
 
#define IMG_LOAD(x)
 
#define IMG_SAVE(x)
 
#define FLOODFILL_FIFO_SIZE   0x1000
 
#define FLOODFILL_FIFO_MASK   (FLOODFILL_FIFO_SIZE - 1)
 
#define FLOODFILL_STEP(off, dx, dy)
 
#define RIMAGES_HASH   256
 

Functions

void stbi_write (void *context, void *data, int size)
 
static void IMG_FloodFill (byte *skin, int skinwidth, int skinheight)
 
static qerror_t IMG_DecodePCX (byte *rawdata, size_t rawlen, byte *pixels, byte *palette, int *width, int *height)
 
static int IMG_Unpack8 (uint32_t *out, const uint8_t *in, int width, int height)
 
 IMG_LOAD (PCX)
 
 IMG_LOAD (WAL)
 
 IMG_LOAD (STB)
 
 IMG_SAVE (TGA)
 
 IMG_SAVE (JPG)
 
 IMG_SAVE (PNG)
 
static qhandle_t create_screenshot (char *buffer, size_t size, const char *name, const char *ext)
 
static void make_screenshot (const char *name, const char *ext, qerror_t(*save)(qhandle_t, const char *, byte *, int, int, int, int), int param)
 
static void IMG_ScreenShot_f (void)
 
static void IMG_ScreenShotTGA_f (void)
 
static void IMG_ScreenShotJPG_f (void)
 
static void IMG_ScreenShotPNG_f (void)
 
void IMG_ResampleTexture (const byte *in, int inwidth, int inheight, byte *out, int outwidth, int outheight)
 
void IMG_MipMap (byte *out, byte *in, int width, int height)
 
static void IMG_List_f (void)
 
static image_talloc_image (void)
 
static image_tlookup_image (const char *name, imagetype_t type, unsigned hash, size_t baselen)
 
static int _try_image_format (imageformat_t fmt, image_t *image, byte **pic)
 
static int try_image_format (imageformat_t fmt, image_t *image, byte **pic)
 
static int try_other_formats (imageformat_t orig, image_t *image, byte **pic)
 
static void get_image_dimensions (imageformat_t fmt, image_t *image)
 
static void r_texture_formats_changed (cvar_t *self)
 
qerror_t load_img (const char *name, image_t *image)
 
static qerror_t find_or_load_image (const char *name, size_t len, imagetype_t type, imageflags_t flags, image_t **image_p)
 
image_tIMG_Find (const char *name, imagetype_t type, imageflags_t flags)
 
image_tIMG_ForHandle (qhandle_t h)
 
qhandle_t R_RegisterImage (const char *name, imagetype_t type, imageflags_t flags, qerror_t *err_p)
 
qhandle_t R_RegisterRawImage (const char *name, int width, int height, byte *pic, imagetype_t type, imageflags_t flags)
 
void R_UnregisterImage (qhandle_t handle)
 
qboolean R_GetPicSize (int *w, int *h, qhandle_t pic)
 
void IMG_FreeUnused (void)
 
void IMG_FreeAll (void)
 
void IMG_GetPalette (void)
 
void IMG_Init (void)
 
void IMG_Shutdown (void)
 

Variables

cvar_t * vid_rtx
 
static cvar_t * r_screenshot_format
 
static cvar_t * r_screenshot_quality
 
static cvar_t * r_screenshot_compression
 
static list_t r_imageHash [RIMAGES_HASH]
 
image_t r_images [MAX_RIMAGES]
 
int r_numImages
 
uint32_t d_8to24table [256]
 
struct {
   char   ext [4]
 
   qerror_t(*   load )(byte *, size_t, image_t
      *, byte **)
 
img_loaders [IM_MAX]
 
static imageformat_t img_search [IM_MAX]
 
static int img_total
 
static cvar_t * r_override_textures
 
static cvar_t * r_texture_formats
 
static const cmdreg_t img_cmd []
 

Macro Definition Documentation

◆ FLOODFILL_FIFO_MASK

#define FLOODFILL_FIFO_MASK   (FLOODFILL_FIFO_SIZE - 1)

Definition at line 66 of file images.c.

◆ FLOODFILL_FIFO_SIZE

#define FLOODFILL_FIFO_SIZE   0x1000

Definition at line 65 of file images.c.

◆ FLOODFILL_STEP

#define FLOODFILL_STEP (   off,
  dx,
  dy 
)
Value:
do { \
if (pos[off] == fillcolor) { \
pos[off] = 255; \
fifo[inpt].x = x + (dx); \
fifo[inpt].y = y + (dy); \
inpt = (inpt + 1) & FLOODFILL_FIFO_MASK; \
} else if (pos[off] != 255) { \
fdc = pos[off]; \
} \
} while(0)

Definition at line 68 of file images.c.

◆ IMG_LOAD

#define IMG_LOAD (   x)
Value:
static qerror_t IMG_Load##x(byte *rawdata, size_t rawlen, \
image_t *image, byte **pic)

Definition at line 37 of file images.c.

◆ IMG_SAVE

#define IMG_SAVE (   x)
Value:
static qerror_t IMG_Save##x(qhandle_t f, const char *filename, \
byte *pic, int width, int height, int row_stride, int param)

Definition at line 41 of file images.c.

◆ R_COLORMAP_PCX

#define R_COLORMAP_PCX   "pics/colormap.pcx"

Definition at line 35 of file images.c.

◆ RIMAGES_HASH

#define RIMAGES_HASH   256

Definition at line 647 of file images.c.

Function Documentation

◆ _try_image_format()

static int _try_image_format ( imageformat_t  fmt,
image_t image,
byte **  pic 
)
static

Definition at line 787 of file images.c.

788 {
789  byte *data;
790  ssize_t len;
791  qerror_t ret;
792 
793  // load the file
794  len = FS_LoadFile(image->name, (void **)&data);
795  if (!data) {
796  return len;
797  }
798 
799  // decompress the image
800  ret = img_loaders[fmt].load(data, len, image, pic);
801 
802  FS_FreeFile(data);
803 
804  image->filepath[0] = 0;
805  if (ret >= 0) {
806  strcpy(image->filepath, image->name);
807  // record last modified time (skips reload when invoking IMG_ReloadAll)
808  image->last_modified = 0;
809  FS_LastModified(image->filepath, &image->last_modified);
810  }
811  return ret < 0 ? ret : fmt;
812 }

Referenced by find_or_load_image(), load_img(), and try_image_format().

◆ alloc_image()

static image_t* alloc_image ( void  )
static

Definition at line 744 of file images.c.

745 {
746  int i;
747  image_t *image;
748 
749  // find a free image_t slot
750  for (i = 1, image = r_images + 1; i < r_numImages; i++, image++) {
751  if (!image->registration_sequence)
752  break;
753  }
754 
755  if (i == r_numImages) {
756  if (r_numImages == MAX_RIMAGES)
757  return NULL;
758  r_numImages++;
759  }
760 
761  return image;
762 }

Referenced by find_or_load_image(), and R_RegisterRawImage().

◆ create_screenshot()

static qhandle_t create_screenshot ( char *  buffer,
size_t  size,
const char *  name,
const char *  ext 
)
static

Definition at line 415 of file images.c.

417 {
418  qhandle_t f;
419  qerror_t ret;
420  int i;
421 
422  if (name && *name) {
423  // save to user supplied name
424  return FS_EasyOpenFile(buffer, size, FS_MODE_WRITE,
425  "screenshots/", name, ext);
426  }
427 
428  // find a file name to save it to
429  for (i = 0; i < 1000; i++) {
430  Q_snprintf(buffer, size, "screenshots/quake%03d%s", i, ext);
431  ret = FS_FOpenFile(buffer, &f, FS_MODE_WRITE | FS_FLAG_EXCL);
432  if (f) {
433  return f;
434  }
435  if (ret != Q_ERR_EXIST) {
436  Com_EPrintf("Couldn't exclusively open %s for writing: %s\n",
437  buffer, Q_ErrorString(ret));
438  return 0;
439  }
440  }
441 
442  Com_EPrintf("All screenshot slots are full.\n");
443  return 0;
444 }

Referenced by make_screenshot().

◆ find_or_load_image()

static qerror_t find_or_load_image ( const char *  name,
size_t  len,
imagetype_t  type,
imageflags_t  flags,
image_t **  image_p 
)
static

Definition at line 991 of file images.c.

994 {
995  image_t *image;
996  byte *pic;
997  unsigned hash;
998  imageformat_t fmt;
999  qerror_t ret;
1000 
1001  *image_p = NULL;
1002 
1003  // must have an extension and at least 1 char of base name
1004  if (len <= 4) {
1005  return Q_ERR_NAMETOOSHORT;
1006  }
1007  if (name[len - 4] != '.') {
1008  return Q_ERR_INVALID_PATH;
1009  }
1010 
1011  hash = FS_HashPathLen(name, len - 4, RIMAGES_HASH);
1012 
1013  // look for it
1014  if ((image = lookup_image(name, type, hash, len - 4)) != NULL) {
1015  image->flags |= flags & IF_PERMANENT;
1016  image->registration_sequence = registration_sequence;
1017  *image_p = image;
1018  return Q_ERR_SUCCESS;
1019  }
1020 
1021  // allocate image slot
1022  image = alloc_image();
1023  if (!image) {
1024  return Q_ERR_OUT_OF_SLOTS;
1025  }
1026 
1027  int override_textures = !!r_override_textures->integer;
1028  if (!vid_rtx->integer && (type != IT_PIC))
1029  override_textures = 0;
1030 
1031  for (int use_override = override_textures; use_override >= 0; use_override--)
1032  {
1033  // fill in some basic info
1034  if (use_override)
1035  {
1036  const char* last_slash = strrchr(name, '/');
1037  if (!last_slash)
1038  last_slash = name;
1039  else
1040  last_slash += 1;
1041 
1042  strcpy(image->name, "overrides/");
1043  strcat(image->name, last_slash);
1044  image->baselen = strlen(image->name) - 4;
1045  }
1046  else
1047  {
1048  memcpy(image->name, name, len + 1);
1049  image->baselen = len - 4;
1050  }
1051  image->type = type;
1052  image->flags = flags;
1053  image->registration_sequence = registration_sequence;
1054 
1055  // find out original extension
1056  for (fmt = 0; fmt < IM_MAX; fmt++) {
1057  if (!Q_stricmp(image->name + image->baselen + 1, img_loaders[fmt].ext)) {
1058  break;
1059  }
1060  }
1061 
1062  // load the pic from disk
1063  pic = NULL;
1064 
1065  if (fmt == IM_MAX) {
1066  // unknown extension, but give it a chance to load anyway
1067  ret = try_other_formats(IM_MAX, image, &pic);
1068  if (ret == Q_ERR_NOENT) {
1069  // not found, change error to invalid path
1070  ret = Q_ERR_INVALID_PATH;
1071  }
1072  }
1073  else if (override_textures) {
1074  // forcibly replace the extension
1075  ret = try_other_formats(IM_MAX, image, &pic);
1076  }
1077  else {
1078  // first try with original extension
1079  ret = _try_image_format(fmt, image, &pic);
1080  if (ret == Q_ERR_NOENT) {
1081  // retry with remaining extensions
1082  ret = try_other_formats(fmt, image, &pic);
1083  }
1084  }
1085 
1086  // record last modified time (skips reload when invoking IMG_ReloadAll)
1087  image->last_modified = 0;
1088  FS_LastModified(image->name, &image->last_modified);
1089 
1090  if (use_override)
1091  {
1092  memcpy(image->name, name, len + 1);
1093  image->baselen = len - 4;
1094  }
1095 
1096  // if we are replacing 8-bit texture with a higher resolution 32-bit
1097  // texture, we need to recover original image dimensions
1098  if (fmt <= IM_WAL && ret > IM_WAL) {
1099  get_image_dimensions(fmt, image);
1100  }
1101 
1102  if(ret >= 0)
1103  break;
1104  }
1105 
1106  if (ret < 0) {
1107  memset(image, 0, sizeof(*image));
1108  return ret;
1109  }
1110 
1111  List_Append(&r_imageHash[hash], &image->entry);
1112 
1113  image->is_srgb = !!(flags & IF_SRGB);
1114 
1115  // upload the image
1116  IMG_Load(image, pic);
1117 
1118  *image_p = image;
1119  return Q_ERR_SUCCESS;
1120 }

Referenced by IMG_Find(), and R_RegisterImage().

◆ get_image_dimensions()

static void get_image_dimensions ( imageformat_t  fmt,
image_t image 
)
static

Definition at line 851 of file images.c.

852 {
853  char buffer[MAX_QPATH];
854  ssize_t len;
855  miptex_t mt;
856  dpcx_t pcx;
857  qhandle_t f;
858  unsigned w, h;
859 
860  memcpy(buffer, image->name, image->baselen + 1);
861 
862  w = h = 0;
863  if (fmt == IM_WAL) {
864  memcpy(buffer + image->baselen + 1, "wal", 4);
865  FS_FOpenFile(buffer, &f, FS_MODE_READ);
866  if (f) {
867  len = FS_Read(&mt, sizeof(mt), f);
868  if (len == sizeof(mt)) {
869  w = LittleLong(mt.width);
870  h = LittleLong(mt.height);
871  }
872  FS_FCloseFile(f);
873  }
874  } else {
875  memcpy(buffer + image->baselen + 1, "pcx", 4);
876  FS_FOpenFile(buffer, &f, FS_MODE_READ);
877  if (f) {
878  len = FS_Read(&pcx, sizeof(pcx), f);
879  if (len == sizeof(pcx)) {
880  w = LittleShort(pcx.xmax) + 1;
881  h = LittleShort(pcx.ymax) + 1;
882  }
883  FS_FCloseFile(f);
884  }
885  }
886 
887  if (w < 1 || h < 1 || w > 512 || h > 512) {
888  return;
889  }
890 
891  image->width = w;
892  image->height = h;
893 }

Referenced by find_or_load_image(), and load_img().

◆ IMG_DecodePCX()

static qerror_t IMG_DecodePCX ( byte *  rawdata,
size_t  rawlen,
byte *  pixels,
byte *  palette,
int width,
int height 
)
static

Definition at line 127 of file images.c.

129 {
130  byte *raw, *end;
131  dpcx_t *pcx;
132  int x, y, w, h, scan;
133  int dataByte, runLength;
134 
135  //
136  // parse the PCX file
137  //
138  if (rawlen < sizeof(dpcx_t)) {
139  return Q_ERR_FILE_TOO_SMALL;
140  }
141 
142  pcx = (dpcx_t *)rawdata;
143 
144  if (pcx->manufacturer != 10 || pcx->version != 5) {
145  return Q_ERR_UNKNOWN_FORMAT;
146  }
147 
148  if (pcx->encoding != 1 || pcx->bits_per_pixel != 8) {
149  return Q_ERR_INVALID_FORMAT;
150  }
151 
152  w = (LittleShort(pcx->xmax) - LittleShort(pcx->xmin)) + 1;
153  h = (LittleShort(pcx->ymax) - LittleShort(pcx->ymin)) + 1;
154  if (w < 1 || h < 1 || w > 640 || h > 480) {
155  return Q_ERR_INVALID_FORMAT;
156  }
157 
158  if (pcx->color_planes != 1) {
159  return Q_ERR_INVALID_FORMAT;
160  }
161 
162  scan = LittleShort(pcx->bytes_per_line);
163  if (scan < w) {
164  return Q_ERR_INVALID_FORMAT;
165  }
166 
167  //
168  // get palette
169  //
170  if (palette) {
171  if (rawlen < 768) {
172  return Q_ERR_FILE_TOO_SMALL;
173  }
174  memcpy(palette, (byte *)pcx + rawlen - 768, 768);
175  }
176 
177  //
178  // get pixels
179  //
180  if (pixels) {
181  raw = pcx->data;
182  end = (byte *)pcx + rawlen;
183  for (y = 0; y < h; y++, pixels += w) {
184  for (x = 0; x < scan;) {
185  if (raw >= end)
186  return Q_ERR_BAD_RLE_PACKET;
187  dataByte = *raw++;
188 
189  if ((dataByte & 0xC0) == 0xC0) {
190  runLength = dataByte & 0x3F;
191  if (x + runLength > scan)
192  return Q_ERR_BAD_RLE_PACKET;
193  if (raw >= end)
194  return Q_ERR_BAD_RLE_PACKET;
195  dataByte = *raw++;
196  } else {
197  runLength = 1;
198  }
199 
200  while (runLength--) {
201  if (x < w)
202  pixels[x] = dataByte;
203  x++;
204  }
205  }
206  }
207  }
208 
209  if (width)
210  *width = w;
211  if (height)
212  *height = h;
213 
214  return Q_ERR_SUCCESS;
215 }

Referenced by IMG_GetPalette(), and IMG_LOAD().

◆ IMG_Find()

image_t* IMG_Find ( const char *  name,
imagetype_t  type,
imageflags_t  flags 
)

Definition at line 1122 of file images.c.

1123 {
1124  image_t *image;
1125  size_t len;
1126  qerror_t ret;
1127 
1128  if (!name) {
1129  Com_Error(ERR_FATAL, "%s: NULL", __func__);
1130  }
1131 
1132  // this should never happen
1133  len = strlen(name);
1134  if (len >= MAX_QPATH) {
1135  Com_Error(ERR_FATAL, "%s: oversize name", __func__);
1136  }
1137 
1138  ret = find_or_load_image(name, len, type, flags, &image);
1139  if (image) {
1140  return image;
1141  }
1142 
1143  // don't spam about missing images
1144  if (ret != Q_ERR_NOENT) {
1145  Com_EPrintf("Couldn't load %s: %s\n", name, Q_ErrorString(ret));
1146  }
1147 
1148  return R_NOTEXTURE;
1149 }

Referenced by bsp_mesh_register_textures(), GL_LoadWorld(), MOD_LoadMD2(), MOD_LoadMD2_GL(), MOD_LoadMD2_RTX(), MOD_LoadSP2(), ProcessTexinfo(), R_SetSky(), R_SetSky_GL(), R_SetSky_RTX(), vkpt_initialize_all(), vkpt_physical_sky_endRegistration(), and vkpt_textures_prefetch().

◆ IMG_FloodFill()

static void IMG_FloodFill ( byte *  skin,
int  skinwidth,
int  skinheight 
)
static

Definition at line 87 of file images.c.

88 {
89  byte fillcolor = *skin; // assume this is the pixel to fill
91  int inpt = 0, outpt = 0;
92  int filledcolor = 0; // FIXME: fixed black
93 
94  // can't fill to filled color or to transparent color
95  // (used as visited marker)
96  if (fillcolor == filledcolor || fillcolor == 255) {
97  return;
98  }
99 
100  fifo[inpt].x = 0, fifo[inpt].y = 0;
101  inpt = (inpt + 1) & FLOODFILL_FIFO_MASK;
102 
103  while (outpt != inpt) {
104  int x = fifo[outpt].x, y = fifo[outpt].y;
105  int fdc = filledcolor;
106  byte *pos = &skin[x + skinwidth * y];
107 
108  outpt = (outpt + 1) & FLOODFILL_FIFO_MASK;
109 
110  if (x > 0) FLOODFILL_STEP(-1, -1, 0);
111  if (x < skinwidth - 1) FLOODFILL_STEP(1, 1, 0);
112  if (y > 0) FLOODFILL_STEP(-skinwidth, 0, -1);
113  if (y < skinheight - 1) FLOODFILL_STEP(skinwidth, 0, 1);
114 
115  skin[x + skinwidth * y] = fdc;
116  }
117 }

Referenced by IMG_LOAD().

◆ IMG_ForHandle()

image_t* IMG_ForHandle ( qhandle_t  h)

Definition at line 1156 of file images.c.

1157 {
1158  if (h < 0 || h >= r_numImages) {
1159  Com_Error(ERR_FATAL, "%s: %d out of range", __func__, h);
1160  }
1161 
1162  return &r_images[h];
1163 }

Referenced by get_mesh_material(), R_AliasSetupSkin(), R_DrawChar(), R_DrawChar_GL(), R_DrawPic(), R_DrawPic_GL(), R_DrawPic_RTX(), R_DrawStretchPic(), R_DrawStretchPic_GL(), R_DrawString(), R_DrawString_GL(), R_GetPicSize(), R_TileClear(), R_TileClear_GL(), SCR_DrawActive(), and texnum_for_mesh().

◆ IMG_FreeAll()

void IMG_FreeAll ( void  )

Definition at line 1343 of file images.c.

1344 {
1345  image_t *image;
1346  int i, count = 0;
1347 
1348  for (i = 1, image = r_images + 1; i < r_numImages; i++, image++) {
1349  if (!image->registration_sequence)
1350  continue; // free image_t slot
1351  // free it
1352  IMG_Unload(image);
1353 
1354  memset(image, 0, sizeof(*image));
1355  count++;
1356  }
1357 
1358  if (count) {
1359  Com_DPrintf("%s: %i images freed\n", __func__, count);
1360  }
1361 
1362  for (i = 0; i < RIMAGES_HASH; i++) {
1363  List_Init(&r_imageHash[i]);
1364  }
1365 
1366  // &r_images[0] == R_NOTEXTURE
1367  r_numImages = 1;
1368 }

Referenced by GL_ShutdownImages(), R_Shutdown_RTX(), and R_ShutdownImages().

◆ IMG_FreeUnused()

void IMG_FreeUnused ( void  )

Definition at line 1310 of file images.c.

1311 {
1312  image_t *image;
1313  int i, count = 0;
1314 
1315  for (i = 1, image = r_images + 1; i < r_numImages; i++, image++) {
1316  if (image->registration_sequence == registration_sequence) {
1317 #if USE_REF == REF_SOFT
1318  // TODO: account for MIPSIZE, TEX_BYTES
1319  Com_PageInMemory(image->pixels[0], image->upload_width * image->upload_height * 4);
1320 #endif
1321  continue; // used this sequence
1322  }
1323  if (!image->registration_sequence)
1324  continue; // free image_t slot
1325  if (image->flags & (IF_PERMANENT | IF_SCRAP))
1326  continue; // don't free pics
1327 
1328  // delete it from hash table
1329  List_Remove(&image->entry);
1330 
1331  // free it
1332  IMG_Unload(image);
1333 
1334  memset(image, 0, sizeof(*image));
1335  count++;
1336  }
1337 
1338  if (count) {
1339  Com_DPrintf("%s: %i images freed\n", __func__, count);
1340  }
1341 }

Referenced by R_EndRegistration(), R_EndRegistration_GL(), R_EndRegistration_RTX(), and R_UnregisterImage().

◆ IMG_GetPalette()

void IMG_GetPalette ( void  )

Definition at line 1376 of file images.c.

1377 {
1378  byte pal[768], *src, *data;
1379  qerror_t ret;
1380  ssize_t len;
1381  int i;
1382 
1383  // get the palette
1384  len = FS_LoadFile(R_COLORMAP_PCX, (void **)&data);
1385  if (!data) {
1386  ret = len;
1387  goto fail;
1388  }
1389 
1390  ret = IMG_DecodePCX(data, len, NULL, pal, NULL, NULL);
1391 
1392  FS_FreeFile(data);
1393 
1394  if (ret < 0) {
1395  goto fail;
1396  }
1397 
1398  for (i = 0, src = pal; i < 255; i++, src += 3) {
1399  d_8to24table[i] = MakeColor(src[0], src[1], src[2], 255);
1400  }
1401 
1402  // 255 is transparent
1403  d_8to24table[i] = MakeColor(src[0], src[1], src[2], 0);
1404  return;
1405 
1406 fail:
1407  Com_Error(ERR_FATAL, "Couldn't load %s: %s", R_COLORMAP_PCX, Q_ErrorString(ret));
1408 }

Referenced by GL_InitImages(), R_Init_RTX(), and R_InitImages().

◆ IMG_Init()

void IMG_Init ( void  )

Definition at line 1419 of file images.c.

1420 {
1421  int i;
1422 
1423  if (r_numImages) {
1424  Com_Error(ERR_FATAL, "%s: %d images not freed", __func__, r_numImages);
1425  }
1426 
1427 
1428  r_override_textures = Cvar_Get("r_override_textures", "1", CVAR_FILES);
1429  r_texture_formats = Cvar_Get("r_texture_formats", "pjt", 0);
1432 
1433  r_screenshot_format = Cvar_Get("gl_screenshot_format", "jpg", 0);
1434  r_screenshot_format = Cvar_Get("gl_screenshot_format", "png", 0);
1435  r_screenshot_quality = Cvar_Get("gl_screenshot_quality", "100", 0);
1436  r_screenshot_compression = Cvar_Get("gl_screenshot_compression", "6", 0);
1437 
1439 
1440  for (i = 0; i < RIMAGES_HASH; i++) {
1441  List_Init(&r_imageHash[i]);
1442  }
1443 
1444  // &r_images[0] == R_NOTEXTURE
1445  r_numImages = 1;
1446 }

Referenced by GL_InitImages(), R_Init(), and R_Init_RTX().

◆ IMG_List_f()

static void IMG_List_f ( void  )
static

Definition at line 678 of file images.c.

679 {
680  int i;
681  image_t *image;
682  int texels, count;
683 
684  if (Cmd_Argc() > 1) {
685 
686  // save to file
687  char path[MAX_OSPATH];
688 
689  qhandle_t f = FS_EasyOpenFile(path, sizeof(path), FS_MODE_WRITE | FS_FLAG_TEXT, "", Cmd_Argv(1), ".csv");
690  if (!f) {
691  Com_EPrintf("Error opening '%s'\n", path);
692  return;
693  }
694 
695  for (i = 1, count = 0, image = r_images + 1; i < r_numImages; i++, image++) {
696 
697  if (!image->registration_sequence)
698  continue;
699 
700  char fmt[MAX_QPATH];
701  sprintf(fmt, "%%-%ds, %%-%ds, (%% 5d %% 5d), sRGB:%%d\n", MAX_QPATH, MAX_QPATH);
702 
703  FS_FPrintf(f, fmt,
704  image->name,
705  image->filepath,
706  image->width,
707  image->height,
708  image->is_srgb);
709  }
710  FS_FCloseFile(f);
711 
712  Com_Printf("Saved '%s'\n", path);
713 
714  } else {
715 
716  // dump to console
717  static const char types[8] = "PFMSWY??";
718 
719  Com_Printf("------------------\n");
720  texels = count = 0;
721 
722  for (i = 1, image = r_images + 1; i < r_numImages; i++, image++) {
723  if (!image->registration_sequence)
724  continue;
725 
726  Com_Printf("%c%c%c%c %4i %4i %s: %s\n",
727  types[image->type > IT_MAX ? IT_MAX : image->type],
728  (image->flags & IF_TRANSPARENT) ? 'T' : ' ',
729  (image->flags & IF_SCRAP) ? 'S' : ' ',
730  (image->flags & IF_PERMANENT) ? '*' : ' ',
731  image->upload_width,
732  image->upload_height,
733  (image->flags & IF_PALETTED) ? "PAL" : "RGB",
734  image->name);
735 
736  texels += image->upload_width * image->upload_height;
737  count++;
738  }
739  Com_Printf("Total images: %d (out of %d slots)\n", count, r_numImages);
740  Com_Printf("Total texels: %d (not counting mipmaps)\n", texels);
741  }
742 }

◆ IMG_LOAD() [1/3]

IMG_LOAD ( PCX  )

Definition at line 268 of file images.c.

269 {
270  byte buffer[640 * 480];
271  int w, h;
272  qerror_t ret;
273 
274  ret = IMG_DecodePCX(rawdata, rawlen, buffer, NULL, &w, &h);
275  if (ret < 0)
276  return ret;
277 
278  if (image->type == IT_SKIN)
279  IMG_FloodFill(buffer, w, h);
280 
281  *pic = IMG_AllocPixels(w * h * 4);
282 
283  image->upload_width = image->width = w;
284  image->upload_height = image->height = h;
285  image->flags |= IMG_Unpack8((uint32_t *)*pic, buffer, w, h);
286 
287  return Q_ERR_SUCCESS;
288 }

◆ IMG_LOAD() [2/3]

IMG_LOAD ( STB  )

Definition at line 341 of file images.c.

342 {
343  int w, h, channels;
344  byte* data = stbi_load_from_memory(rawdata, rawlen, &w, &h, &channels, 4);
345 
346  if (!data)
347  return Q_ERR_LIBRARY_ERROR;
348 
349  *pic = data;
350 
351  image->upload_width = image->width = w;
352  image->upload_height = image->height = h;
353 
354  if (channels == 3)
355  image->flags |= IF_OPAQUE;
356 
357  return Q_ERR_SUCCESS;
358 }

◆ IMG_LOAD() [3/3]

IMG_LOAD ( WAL  )

Definition at line 299 of file images.c.

300 {
301  miptex_t *mt;
302  size_t w, h, offset, size, endpos;
303 
304  if (rawlen < sizeof(miptex_t)) {
305  return Q_ERR_FILE_TOO_SMALL;
306  }
307 
308  mt = (miptex_t *)rawdata;
309 
310  w = LittleLong(mt->width);
311  h = LittleLong(mt->height);
312  if (w < 1 || h < 1 || w > 512 || h > 512) {
313  return Q_ERR_INVALID_FORMAT;
314  }
315 
316  size = w * h;
317 
318  offset = LittleLong(mt->offsets[0]);
319  endpos = offset + size;
320  if (endpos < offset || endpos > rawlen) {
321  return Q_ERR_BAD_EXTENT;
322  }
323 
324  *pic = IMG_AllocPixels(size * 4);
325 
326  image->upload_width = image->width = w;
327  image->upload_height = image->height = h;
328  image->flags |= IMG_Unpack8((uint32_t *)*pic, (uint8_t *)mt + offset, w, h);
329 
330  return Q_ERR_SUCCESS;
331 }

◆ IMG_MipMap()

void IMG_MipMap ( byte *  out,
byte *  in,
int  width,
int  height 
)

Definition at line 623 of file images.c.

624 {
625  int i, j;
626 
627  width <<= 2;
628  height >>= 1;
629  for (i = 0; i < height; i++, in += width) {
630  for (j = 0; j < width; j += 8, out += 4, in += 8) {
631  out[0] = (in[0] + in[4] + in[width + 0] + in[width + 4]) >> 2;
632  out[1] = (in[1] + in[5] + in[width + 1] + in[width + 5]) >> 2;
633  out[2] = (in[2] + in[6] + in[width + 2] + in[width + 6]) >> 2;
634  out[3] = (in[3] + in[7] + in[width + 3] + in[width + 7]) >> 2;
635  }
636  }
637 }

Referenced by GL_Upload32(), and IMG_Load().

◆ IMG_ResampleTexture()

void IMG_ResampleTexture ( const byte *  in,
int  inwidth,
int  inheight,
byte *  out,
int  outwidth,
int  outheight 
)

Definition at line 577 of file images.c.

579 {
580  int i, j;
581  const byte *inrow1, *inrow2;
582  unsigned frac, fracstep;
583  unsigned p1[MAX_TEXTURE_SIZE], p2[MAX_TEXTURE_SIZE];
584  const byte *pix1, *pix2, *pix3, *pix4;
585  float heightScale;
586 
587  if (outwidth > MAX_TEXTURE_SIZE) {
588  Com_Error(ERR_FATAL, "%s: outwidth > %d", __func__, MAX_TEXTURE_SIZE);
589  }
590 
591  fracstep = inwidth * 0x10000 / outwidth;
592 
593  frac = fracstep >> 2;
594  for (i = 0; i < outwidth; i++) {
595  p1[i] = 4 * (frac >> 16);
596  frac += fracstep;
597  }
598  frac = 3 * (fracstep >> 2);
599  for (i = 0; i < outwidth; i++) {
600  p2[i] = 4 * (frac >> 16);
601  frac += fracstep;
602  }
603 
604  heightScale = (float)inheight / outheight;
605  inwidth <<= 2;
606  for (i = 0; i < outheight; i++) {
607  inrow1 = in + inwidth * (int)((i + 0.25f) * heightScale);
608  inrow2 = in + inwidth * (int)((i + 0.75f) * heightScale);
609  for (j = 0; j < outwidth; j++) {
610  pix1 = inrow1 + p1[j];
611  pix2 = inrow1 + p2[j];
612  pix3 = inrow2 + p1[j];
613  pix4 = inrow2 + p2[j];
614  out[0] = (pix1[0] + pix2[0] + pix3[0] + pix4[0]) >> 2;
615  out[1] = (pix1[1] + pix2[1] + pix3[1] + pix4[1]) >> 2;
616  out[2] = (pix1[2] + pix2[2] + pix3[2] + pix4[2]) >> 2;
617  out[3] = (pix1[3] + pix2[3] + pix3[3] + pix4[3]) >> 2;
618  out += 4;
619  }
620  }
621 }

Referenced by GL_Upload32(), and IMG_Load().

◆ IMG_SAVE() [1/3]

IMG_SAVE ( JPG  )

Definition at line 380 of file images.c.

381 {
382  stbi_flip_vertically_on_write(1);
383  int ret = stbi_write_jpg_to_func(stbi_write, (void*)(size_t)f, width, height, 3, pic, param);
384 
385  if (ret)
386  return Q_ERR_SUCCESS;
387 
388  return Q_ERR_LIBRARY_ERROR;
389 }

◆ IMG_SAVE() [2/3]

IMG_SAVE ( PNG  )

Definition at line 392 of file images.c.

393 {
394  stbi_flip_vertically_on_write(1);
395  int ret = stbi_write_png_to_func(stbi_write, (void*)(size_t)f, width, height, 3, pic, row_stride);
396 
397  if (ret)
398  return Q_ERR_SUCCESS;
399 
400  return Q_ERR_LIBRARY_ERROR;
401 }

◆ IMG_SAVE() [3/3]

IMG_SAVE ( TGA  )

Definition at line 369 of file images.c.

370 {
371  stbi_flip_vertically_on_write(1);
372  int ret = stbi_write_tga_to_func(stbi_write, (void*)(size_t)f, width, height, 3, pic);
373 
374  if (ret)
375  return Q_ERR_SUCCESS;
376 
377  return Q_ERR_LIBRARY_ERROR;
378 }

◆ IMG_ScreenShot_f()

static void IMG_ScreenShot_f ( void  )
static

Definition at line 484 of file images.c.

485 {
486  const char *s;
487 
488  if (Cmd_Argc() > 2) {
489  Com_Printf("Usage: %s [format]\n", Cmd_Argv(0));
490  return;
491  }
492 
493  if (Cmd_Argc() > 1) {
494  s = Cmd_Argv(1);
495  } else {
496  s = r_screenshot_format->string;
497  }
498 
499  if (*s == 'j') {
500  make_screenshot(NULL, ".jpg", IMG_SaveJPG,
501  r_screenshot_quality->integer);
502  return;
503  }
504 
505  if (*s == 'p') {
506  make_screenshot(NULL, ".png", IMG_SavePNG,
507  r_screenshot_compression->integer);
508  return;
509  }
510 
511  make_screenshot(NULL, ".tga", IMG_SaveTGA, 0);
512 }

◆ IMG_ScreenShotJPG_f()

static void IMG_ScreenShotJPG_f ( void  )
static

Definition at line 533 of file images.c.

534 {
535  int quality;
536 
537  if (Cmd_Argc() > 3) {
538  Com_Printf("Usage: %s [name] [quality]\n", Cmd_Argv(0));
539  return;
540  }
541 
542  if (Cmd_Argc() > 2) {
543  quality = atoi(Cmd_Argv(2));
544  } else {
545  quality = r_screenshot_quality->integer;
546  }
547 
548  make_screenshot(Cmd_Argv(1), ".jpg", IMG_SaveJPG, quality);
549 }

◆ IMG_ScreenShotPNG_f()

static void IMG_ScreenShotPNG_f ( void  )
static

Definition at line 551 of file images.c.

552 {
553  int compression;
554 
555  if (Cmd_Argc() > 3) {
556  Com_Printf("Usage: %s [name] [compression]\n", Cmd_Argv(0));
557  return;
558  }
559 
560  if (Cmd_Argc() > 2) {
561  compression = atoi(Cmd_Argv(2));
562  } else {
563  compression = r_screenshot_compression->integer;
564  }
565 
566  make_screenshot(Cmd_Argv(1), ".png", IMG_SavePNG, compression);
567 }

◆ IMG_ScreenShotTGA_f()

static void IMG_ScreenShotTGA_f ( void  )
static

Definition at line 523 of file images.c.

524 {
525  if (Cmd_Argc() > 2) {
526  Com_Printf("Usage: %s [name]\n", Cmd_Argv(0));
527  return;
528  }
529 
530  make_screenshot(Cmd_Argv(1), ".tga", IMG_SaveTGA, 0);
531 }

◆ IMG_Shutdown()

void IMG_Shutdown ( void  )

Definition at line 1448 of file images.c.

1449 {
1451  r_numImages = 0;
1452 }

Referenced by GL_ShutdownImages(), R_Shutdown(), and R_Shutdown_RTX().

◆ IMG_Unpack8()

static int IMG_Unpack8 ( uint32_t *  out,
const uint8_t *  in,
int  width,
int  height 
)
static

Definition at line 222 of file images.c.

223 {
224  int x, y, p;
225  qboolean has_alpha = qfalse;
226 
227  for (y = 0; y < height; y++) {
228  for (x = 0; x < width; x++) {
229  p = *in;
230  if (p == 255) {
231  has_alpha = qtrue;
232  // transparent, so scan around for another color
233  // to avoid alpha fringes
234  if (y > 0 && *(in - width) != 255)
235  p = *(in - width);
236  else if (y < height - 1 && *(in + width) != 255)
237  p = *(in + width);
238  else if (x > 0 && *(in - 1) != 255)
239  p = *(in - 1);
240  else if (x < width - 1 && *(in + 1) != 255)
241  p = *(in + 1);
242  else if (y > 0 && x > 0 && *(in - width - 1) != 255)
243  p = *(in - width - 1);
244  else if (y > 0 && x < width - 1 && *(in - width + 1) != 255)
245  p = *(in - width + 1);
246  else if (y < height - 1 && x > 0 && *(in + width - 1) != 255)
247  p = *(in + width - 1);
248  else if (y < height - 1 && x < width - 1 && *(in + width + 1) != 255)
249  p = *(in + width + 1);
250  else
251  p = 0;
252  // copy rgb components
253  *out = d_8to24table[p] & U32_RGB;
254  } else {
255  *out = d_8to24table[p];
256  }
257  in++;
258  out++;
259  }
260  }
261 
262  if (has_alpha)
263  return IF_PALETTED | IF_TRANSPARENT;
264 
265  return IF_PALETTED | IF_OPAQUE;
266 }

Referenced by IMG_LOAD().

◆ load_img()

qerror_t load_img ( const char *  name,
image_t image 
)

Definition at line 927 of file images.c.

928 {
929  byte *pic;
930  imageformat_t fmt;
931  qerror_t ret;
932 
933  size_t len = strlen(name);
934 
935  // must have an extension and at least 1 char of base name
936  if (len <= 4) {
937  return Q_ERR_NAMETOOSHORT;
938  }
939  if (name[len - 4] != '.') {
940  return Q_ERR_INVALID_PATH;
941  }
942 
943  memcpy(image->name, name, len + 1);
944  image->baselen = len - 4;
945  image->type = 0;
946  image->flags = 0;
947  image->registration_sequence = 1;
948 
949  // find out original extension
950  for (fmt = 0; fmt < IM_MAX; fmt++) {
951  if (!Q_stricmp(image->name + image->baselen + 1, img_loaders[fmt].ext)) {
952  break;
953  }
954  }
955 
956  // load the pic from disk
957  pic = NULL;
958 
959  // first try with original extension
960  ret = _try_image_format(fmt, image, &pic);
961  if (ret == Q_ERR_NOENT) {
962  // retry with remaining extensions
963  ret = try_other_formats(fmt, image, &pic);
964  }
965 
966  // if we are replacing 8-bit texture with a higher resolution 32-bit
967  // texture, we need to recover original image dimensions
968  if (fmt <= IM_WAL && ret > IM_WAL) {
969  get_image_dimensions(fmt, image);
970  }
971 
972  // if we are replacing 8-bit texture with a higher resolution 32-bit
973  // texture, we need to recover original image dimensions
974  if (fmt <= IM_WAL && ret > IM_WAL) {
975  get_image_dimensions(fmt, image);
976  }
977 
978  if (ret < 0) {
979  memset(image, 0, sizeof(*image));
980  return ret;
981  }
982 
983 #if USE_REF == REF_VKPT
984  image->pix_data = pic;
985 #endif
986 
987  return Q_ERR_SUCCESS;
988 }

Referenced by IMG_ReloadAll().

◆ lookup_image()

static image_t* lookup_image ( const char *  name,
imagetype_t  type,
unsigned  hash,
size_t  baselen 
)
static

Definition at line 766 of file images.c.

768 {
769  image_t *image;
770 
771  // look for it
772  LIST_FOR_EACH(image_t, image, &r_imageHash[hash], entry) {
773  if (image->type != type) {
774  continue;
775  }
776  if (image->baselen != baselen) {
777  continue;
778  }
779  if (!FS_pathcmpn(image->name, name, baselen)) {
780  return image;
781  }
782  }
783 
784  return NULL;
785 }

Referenced by find_or_load_image(), and R_RegisterRawImage().

◆ make_screenshot()

static void make_screenshot ( const char *  name,
const char *  ext,
qerror_t(*)(qhandle_t, const char *, byte *, int, int, int, int save,
int  param 
)
static

Definition at line 446 of file images.c.

449 {
450  char buffer[MAX_OSPATH];
451  byte *pixels;
452  qerror_t ret;
453  qhandle_t f;
454  int w, h, rowbytes;
455 
456  f = create_screenshot(buffer, sizeof(buffer), name, ext);
457  if (!f) {
458  return;
459  }
460 
461  pixels = IMG_ReadPixels(&w, &h, &rowbytes);
462  ret = save(f, buffer, pixels, w, h, rowbytes, param);
463  FS_FreeTempMem(pixels);
464 
465  FS_FCloseFile(f);
466 
467  if (ret < 0) {
468  Com_EPrintf("Couldn't write %s: %s\n", buffer, Q_ErrorString(ret));
469  } else {
470  Com_Printf("Wrote %s\n", buffer);
471  }
472 }

Referenced by IMG_ScreenShot_f(), IMG_ScreenShotJPG_f(), IMG_ScreenShotPNG_f(), and IMG_ScreenShotTGA_f().

◆ R_GetPicSize()

qboolean R_GetPicSize ( int w,
int h,
qhandle_t  pic 
)

Definition at line 1289 of file images.c.

1290 {
1291  image_t *image = IMG_ForHandle(pic);
1292 
1293  if (w) {
1294  *w = image->width;
1295  }
1296  if (h) {
1297  *h = image->height;
1298  }
1299  return !!(image->flags & IF_TRANSPARENT);
1300 }

Referenced by Parse_Background(), Parse_Banner(), Parse_Bitmap(), Parse_File(), Parse_Footer(), Parse_Plaque(), Push(), scr_crosshair_changed(), SCR_RegisterMedia(), and UI_Init().

◆ R_RegisterImage()

qhandle_t R_RegisterImage ( const char *  name,
imagetype_t  type,
imageflags_t  flags,
qerror_t *  err_p 
)

Definition at line 1170 of file images.c.

1172 {
1173  image_t *image;
1174  char fullname[MAX_QPATH];
1175  size_t len;
1176  qerror_t err;
1177 
1178  // empty names are legal, silently ignore them
1179  if (!*name) {
1180  if (err_p)
1181  *err_p = Q_ERR_NAMETOOSHORT;
1182  return 0;
1183  }
1184 
1185  // no images = not initialized
1186  if (!r_numImages) {
1187  if (err_p)
1188  *err_p = Q_ERR_AGAIN;
1189  return 0;
1190  }
1191 
1192  if (type == IT_SKIN) {
1193  len = FS_NormalizePathBuffer(fullname, name, sizeof(fullname));
1194  } else if (*name == '/' || *name == '\\') {
1195  len = FS_NormalizePathBuffer(fullname, name + 1, sizeof(fullname));
1196  } else {
1197  len = Q_concat(fullname, sizeof(fullname), "pics/", name, NULL);
1198  if (len >= sizeof(fullname)) {
1199  err = Q_ERR_NAMETOOLONG;
1200  goto fail;
1201  }
1202  FS_NormalizePath(fullname, fullname);
1203  len = COM_DefaultExtension(fullname, ".pcx", sizeof(fullname));
1204  }
1205 
1206  if (len >= sizeof(fullname)) {
1207  err = Q_ERR_NAMETOOLONG;
1208  goto fail;
1209  }
1210 
1211  err = find_or_load_image(fullname, len, type, flags, &image);
1212  if (image) {
1213  if (err_p)
1214  *err_p = Q_ERR_SUCCESS;
1215  return image - r_images;
1216  }
1217 
1218 fail:
1219  // don't spam about missing images
1220  if (err_p)
1221  *err_p = err;
1222  else if (err != Q_ERR_NOENT)
1223  Com_EPrintf("Couldn't load %s: %s\n", fullname, Q_ErrorString(err));
1224 
1225  return 0;
1226 }

Referenced by Con_RegisterMedia(), and SCR_RegisterMedia().

◆ R_RegisterRawImage()

qhandle_t R_RegisterRawImage ( const char *  name,
int  width,
int  height,
byte *  pic,
imagetype_t  type,
imageflags_t  flags 
)

Definition at line 1228 of file images.c.

1229 {
1230  image_t *image;
1231  unsigned hash;
1232 
1233  int len = strlen(name);
1234  hash = FS_HashPathLen(name, len, RIMAGES_HASH);
1235 
1236  // look for it
1237  if ((image = lookup_image(name, type, hash, len)) != NULL) {
1238  image->flags |= flags & IF_PERMANENT;
1239  image->registration_sequence = registration_sequence;
1240  return image - r_images;
1241  }
1242 
1243  // allocate image slot
1244  image = alloc_image();
1245  if (!image) {
1246  return 0;
1247  }
1248 
1249  memcpy(image->name, name, len + 1);
1250  image->baselen = len;
1251  image->type = type;
1252  image->flags = flags;
1253  image->registration_sequence = registration_sequence;
1254  image->last_modified = 0;
1255  image->width = width;
1256  image->height = height;
1257  image->upload_width = width;
1258  image->upload_height = height;
1259 
1260  List_Append(&r_imageHash[hash], &image->entry);
1261 
1262  image->is_srgb = !!(flags & IF_SRGB);
1263 
1264  // upload the image
1265  IMG_Load(image, pic);
1266 
1267  return image - r_images;
1268 }

Referenced by SCR_ReadNextFrame().

◆ r_texture_formats_changed()

static void r_texture_formats_changed ( cvar_t *  self)
static

Definition at line 895 of file images.c.

896 {
897  char *s;
898  int i, j;
899 
900  // reset the search order
901  img_total = 0;
902 
903  // parse the string
904  for (s = self->string; *s; s++) {
905  switch (*s) {
906  case 't': case 'T': i = IM_TGA; break;
907  case 'j': case 'J': i = IM_JPG; break;
908  case 'p': case 'P': i = IM_PNG; break;
909  default: continue;
910  }
911 
912  // don't let format to be specified more than once
913  for (j = 0; j < img_total; j++)
914  if (img_search[j] == i)
915  break;
916  if (j != img_total)
917  continue;
918 
919  img_search[img_total++] = i;
920  if (img_total == IM_MAX) {
921  break;
922  }
923  }
924 }

Referenced by IMG_Init().

◆ R_UnregisterImage()

void R_UnregisterImage ( qhandle_t  handle)

Definition at line 1270 of file images.c.

1271 {
1272  if (!handle)
1273  return;
1274 
1275  image_t* image = r_images + handle;
1276 
1277  if (image->registration_sequence)
1278  {
1279  image->registration_sequence = -1;
1280  IMG_FreeUnused();
1281  }
1282 }

Referenced by SCR_RunCinematic(), and SCR_StopCinematic().

◆ stbi_write()

void stbi_write ( void context,
void data,
int  size 
)

Definition at line 45 of file images.c.

46 {
47  FS_Write(data, size, (qhandle_t)(size_t)context);
48 }

Referenced by IMG_SAVE().

◆ try_image_format()

static int try_image_format ( imageformat_t  fmt,
image_t image,
byte **  pic 
)
static

Definition at line 814 of file images.c.

815 {
816  // replace the extension
817  memcpy(image->name + image->baselen + 1, img_loaders[fmt].ext, 4);
818  return _try_image_format(fmt, image, pic);
819 }

Referenced by try_other_formats().

◆ try_other_formats()

static int try_other_formats ( imageformat_t  orig,
image_t image,
byte **  pic 
)
static

Definition at line 823 of file images.c.

824 {
825  imageformat_t fmt;
826  qerror_t ret;
827  int i;
828 
829  // search through all the 32-bit formats
830  for (i = 0; i < img_total; i++) {
831  fmt = img_search[i];
832  if (fmt == orig) {
833  continue; // don't retry twice
834  }
835 
836  ret = try_image_format(fmt, image, pic);
837  if (ret != Q_ERR_NOENT) {
838  return ret; // found something
839  }
840  }
841 
842  // fall back to 8-bit formats
843  fmt = (image->type == IT_WALL) ? IM_WAL : IM_PCX;
844  if (fmt == orig) {
845  return Q_ERR_NOENT; // don't retry twice
846  }
847 
848  return try_image_format(fmt, image, pic);
849 }

Referenced by find_or_load_image(), and load_img().

Variable Documentation

◆ d_8to24table

◆ ext

◆ img_cmd

const cmdreg_t img_cmd[]
static
Initial value:
= {
{ "imagelist", IMG_List_f },
{ "screenshot", IMG_ScreenShot_f },
{ "screenshottga", IMG_ScreenShotTGA_f },
{ "screenshotjpg", IMG_ScreenShotJPG_f },
{ "screenshotpng", IMG_ScreenShotPNG_f },
{ NULL }
}

Definition at line 1410 of file images.c.

Referenced by IMG_Init(), and IMG_Shutdown().

◆ img_loaders

const { ... } img_loaders[IM_MAX]
Initial value:
= {
{ "pcx", IMG_LoadPCX },
{ "wal", IMG_LoadWAL },
{ "tga", IMG_LoadSTB },
{ "jpg", IMG_LoadSTB },
{ "png", IMG_LoadSTB }
}

Referenced by _try_image_format(), find_or_load_image(), load_img(), and try_image_format().

◆ img_search

imageformat_t img_search[IM_MAX]
static

Definition at line 667 of file images.c.

Referenced by r_texture_formats_changed(), and try_other_formats().

◆ img_total

int img_total
static

Definition at line 668 of file images.c.

Referenced by r_texture_formats_changed(), and try_other_formats().

◆ load

qerror_t(* load) (byte *, size_t, image_t *, byte **)

Definition at line 658 of file images.c.

Referenced by R_RegisterModel().

◆ r_imageHash

list_t r_imageHash[RIMAGES_HASH]
static

Definition at line 649 of file images.c.

Referenced by find_or_load_image(), IMG_FreeAll(), IMG_Init(), lookup_image(), and R_RegisterRawImage().

◆ r_images

◆ r_numImages

◆ r_override_textures

cvar_t* r_override_textures
static

Definition at line 670 of file images.c.

Referenced by find_or_load_image(), and IMG_Init().

◆ r_screenshot_compression

cvar_t* r_screenshot_compression
static

Definition at line 413 of file images.c.

Referenced by IMG_Init(), IMG_ScreenShot_f(), and IMG_ScreenShotPNG_f().

◆ r_screenshot_format

cvar_t* r_screenshot_format
static

Definition at line 411 of file images.c.

Referenced by IMG_Init(), and IMG_ScreenShot_f().

◆ r_screenshot_quality

cvar_t* r_screenshot_quality
static

Definition at line 412 of file images.c.

Referenced by IMG_Init(), IMG_ScreenShot_f(), and IMG_ScreenShotJPG_f().

◆ r_texture_formats

cvar_t* r_texture_formats
static

Definition at line 671 of file images.c.

Referenced by IMG_Init().

◆ vid_rtx

cvar_t* vid_rtx

Definition at line 30 of file refresh.c.

Referenced by find_or_load_image().

handle
static void * handle
Definition: dynamic.c:52
r_texture_formats_changed
static void r_texture_formats_changed(cvar_t *self)
Definition: images.c:895
FS_EasyOpenFile
qhandle_t FS_EasyOpenFile(char *buf, size_t size, unsigned mode, const char *dir, const char *name, const char *ext)
Definition: files.c:1846
r_screenshot_compression
static cvar_t * r_screenshot_compression
Definition: images.c:413
height
static int height
Definition: physical_sky.c:39
Q_snprintf
size_t Q_snprintf(char *dest, size_t size, const char *fmt,...)
Definition: shared.c:846
image_t
struct image_s image_t
Definition: material.h:27
FS_Read
ssize_t FS_Read(void *buf, size_t len, qhandle_t f)
Definition: files.c:1547
FS_LastModified
qerror_t FS_LastModified(char const *file, uint64_t *last_modified)
Definition: files.c:1310
channels
channel_t channels[MAX_CHANNELS]
Definition: main.c:29
IMG_Load
void(* IMG_Load)(image_t *image, byte *pic)
Definition: refresh.c:431
r_screenshot_quality
static cvar_t * r_screenshot_quality
Definition: images.c:412
Cvar_Get
cvar_t * Cvar_Get(const char *var_name, const char *var_value, int flags)
Definition: cvar.c:257
Q_ErrorString
const char * Q_ErrorString(qerror_t error)
Definition: error.c:51
r_texture_formats
static cvar_t * r_texture_formats
Definition: images.c:671
FS_FPrintf
ssize_t FS_FPrintf(qhandle_t f, const char *format,...)
Definition: files.c:2039
make_screenshot
static void make_screenshot(const char *name, const char *ext, qerror_t(*save)(qhandle_t, const char *, byte *, int, int, int, int), int param)
Definition: images.c:446
IMG_List_f
static void IMG_List_f(void)
Definition: images.c:678
IMG_FloodFill
static void IMG_FloodFill(byte *skin, int skinwidth, int skinheight)
Definition: images.c:87
floodfill_t::x
short x
Definition: images.c:61
alloc_image
static image_t * alloc_image(void)
Definition: images.c:744
img_cmd
static const cmdreg_t img_cmd[]
Definition: images.c:1410
lookup_image
static image_t * lookup_image(const char *name, imagetype_t type, unsigned hash, size_t baselen)
Definition: images.c:766
try_image_format
static int try_image_format(imageformat_t fmt, image_t *image, byte **pic)
Definition: images.c:814
ext
char ext[4]
Definition: images.c:657
IMG_Unpack8
static int IMG_Unpack8(uint32_t *out, const uint8_t *in, int width, int height)
Definition: images.c:222
IMG_ScreenShot_f
static void IMG_ScreenShot_f(void)
Definition: images.c:484
Cmd_Deregister
void Cmd_Deregister(const cmdreg_t *reg)
Definition: cmd.c:1580
Cmd_Argv
char * Cmd_Argv(int arg)
Definition: cmd.c:899
_try_image_format
static int _try_image_format(imageformat_t fmt, image_t *image, byte **pic)
Definition: images.c:787
Cmd_Argc
int Cmd_Argc(void)
Definition: cmd.c:889
RIMAGES_HASH
#define RIMAGES_HASH
Definition: images.c:647
width
static int width
Definition: physical_sky.c:38
FS_FOpenFile
ssize_t FS_FOpenFile(const char *name, qhandle_t *f, unsigned mode)
Definition: files.c:1692
FLOODFILL_FIFO_MASK
#define FLOODFILL_FIFO_MASK
Definition: images.c:66
FS_NormalizePathBuffer
size_t FS_NormalizePathBuffer(char *out, const char *in, size_t size)
Definition: files.c:400
Com_Error
void Com_Error(error_type_t type, const char *fmt,...)
Definition: g_main.c:258
img_search
static imageformat_t img_search[IM_MAX]
Definition: images.c:667
r_override_textures
static cvar_t * r_override_textures
Definition: images.c:670
r_numImages
int r_numImages
Definition: images.c:652
stbi_write
void stbi_write(void *context, void *data, int size)
Definition: images.c:45
r_imageHash
static list_t r_imageHash[RIMAGES_HASH]
Definition: images.c:649
IMG_ReadPixels
byte *(* IMG_ReadPixels)(int *width, int *height, int *rowbytes)
Definition: refresh.c:432
IMG_ScreenShotJPG_f
static void IMG_ScreenShotJPG_f(void)
Definition: images.c:533
FLOODFILL_FIFO_SIZE
#define FLOODFILL_FIFO_SIZE
Definition: images.c:65
Cmd_Register
void Cmd_Register(const cmdreg_t *reg)
Definition: cmd.c:1572
try_other_formats
static int try_other_formats(imageformat_t orig, image_t *image, byte **pic)
Definition: images.c:823
floodfill_t
Definition: images.c:60
r_images
image_t r_images[MAX_RIMAGES]
Definition: images.c:651
vid_rtx
cvar_t * vid_rtx
Definition: refresh.c:30
IMG_Unload
void(* IMG_Unload)(image_t *image)
Definition: refresh.c:430
FS_Write
ssize_t FS_Write(const void *buf, size_t len, qhandle_t f)
Definition: files.c:1643
find_or_load_image
static qerror_t find_or_load_image(const char *name, size_t len, imagetype_t type, imageflags_t flags, image_t **image_p)
Definition: images.c:991
img_loaders
static const struct @12 img_loaders[IM_MAX]
img_total
static int img_total
Definition: images.c:668
context
static ALCcontext * context
Definition: dynamic.c:54
IMG_ScreenShotPNG_f
static void IMG_ScreenShotPNG_f(void)
Definition: images.c:551
registration_sequence
int registration_sequence
Definition: main.c:34
err
int err
Definition: win.h:24
FLOODFILL_STEP
#define FLOODFILL_STEP(off, dx, dy)
Definition: images.c:68
create_screenshot
static qhandle_t create_screenshot(char *buffer, size_t size, const char *name, const char *ext)
Definition: images.c:415
COM_DefaultExtension
size_t COM_DefaultExtension(char *path, const char *ext, size_t size)
Definition: shared.c:279
IMG_ForHandle
image_t * IMG_ForHandle(qhandle_t h)
Definition: images.c:1156
IMG_FreeUnused
void IMG_FreeUnused(void)
Definition: images.c:1310
FS_FCloseFile
void FS_FCloseFile(qhandle_t f)
Definition: files.c:759
Q_concat
size_t Q_concat(char *dest, size_t size,...)
Definition: shared.c:758
IMG_ScreenShotTGA_f
static void IMG_ScreenShotTGA_f(void)
Definition: images.c:523
Com_PageInMemory
void Com_PageInMemory(void *buffer, size_t size)
Definition: utils.c:383
int
CONST PIXELFORMATDESCRIPTOR int
Definition: wgl.c:26
get_image_dimensions
static void get_image_dimensions(imageformat_t fmt, image_t *image)
Definition: images.c:851
r_screenshot_format
static cvar_t * r_screenshot_format
Definition: images.c:411
floodfill_t::y
short y
Definition: images.c:61
FS_NormalizePath
size_t FS_NormalizePath(char *out, const char *in)
Definition: files.c:331
R_COLORMAP_PCX
#define R_COLORMAP_PCX
Definition: images.c:35
IMG_DecodePCX
static qerror_t IMG_DecodePCX(byte *rawdata, size_t rawlen, byte *pixels, byte *palette, int *width, int *height)
Definition: images.c:127
d_8to24table
uint32_t d_8to24table[256]
Definition: images.c:654