@@ -913,6 +913,110 @@ int bm_is_valid(int handle) {
913913 return (bm_bitmaps[handle % MAX_BITMAPS].handle == handle);
914914}
915915
916+
917+ // Load an image and validate it while retrieving information for later use
918+ // Input: type = current BM_TYPE_*
919+ // n = location in bm_bitmaps[]
920+ // filename = name of the current file
921+ // img_cfp = already open CFILE handle, if available
922+ //
923+ // Output: w = bmp width
924+ // h = bmp height
925+ // bpp = bmp bits per pixel
926+ // c_type = output for an updated BM_TYPE_*
927+ // mm_lvl = number of mipmap levels for the image
928+ // size = size of the data contained in the image
929+ static int bm_load_info (BM_TYPE type, int n, const char *filename, CFILE *img_cfp, int *w, int *h, int *bpp, BM_TYPE *c_type, int *mm_lvl, int *size)
930+ {
931+ int dds_ct;
932+
933+ if (type == BM_TYPE_DDS) {
934+ int dds_error = dds_read_header (filename, img_cfp, w, h, bpp, &dds_ct, mm_lvl, size);
935+
936+ if (dds_error != DDS_ERROR_NONE) {
937+ mprintf ((" DDS ERROR: Couldn't open '%s' -- %s\n " , filename, dds_error_string (dds_error)));
938+ return -1 ;
939+ }
940+
941+ switch (dds_ct) {
942+ case DDS_DXT1:
943+ *c_type = BM_TYPE_DXT1;
944+ break ;
945+
946+ case DDS_DXT3:
947+ *c_type = BM_TYPE_DXT3;
948+ break ;
949+
950+ case DDS_DXT5:
951+ *c_type = BM_TYPE_DXT5;
952+ break ;
953+
954+ case DDS_UNCOMPRESSED:
955+ *c_type = BM_TYPE_DDS;
956+ break ;
957+
958+ case DDS_CUBEMAP_DXT1:
959+ *c_type = BM_TYPE_CUBEMAP_DXT1;
960+ break ;
961+
962+ case DDS_CUBEMAP_DXT3:
963+ *c_type = BM_TYPE_CUBEMAP_DXT3;
964+ break ;
965+
966+ case DDS_CUBEMAP_DXT5:
967+ *c_type = BM_TYPE_CUBEMAP_DXT5;
968+ break ;
969+
970+ case DDS_CUBEMAP_UNCOMPRESSED:
971+ *c_type = BM_TYPE_CUBEMAP_DDS;
972+ break ;
973+
974+ default :
975+ Error (LOCATION, " Bad DDS file compression! Not using DXT1,3,5: %s" , filename);
976+ return -1 ;
977+ }
978+ }
979+ // if its a tga file
980+ else if (type == BM_TYPE_TGA) {
981+ int tga_error = targa_read_header (filename, img_cfp, w, h, bpp, NULL );
982+ if (tga_error != TARGA_ERROR_NONE) {
983+ mprintf ((" tga: Couldn't open '%s'\n " , filename));
984+ return -1 ;
985+ }
986+ }
987+ // if its a png file
988+ else if (type == BM_TYPE_PNG) {
989+ int png_error = png_read_header (filename, img_cfp, w, h, bpp, NULL );
990+ if (png_error != PNG_ERROR_NONE) {
991+ mprintf ((" png: Couldn't open '%s'\n " , filename));
992+ return -1 ;
993+ }
994+ }
995+ // if its a jpg file
996+ else if (type == BM_TYPE_JPG) {
997+ int jpg_error = jpeg_read_header (filename, img_cfp, w, h, bpp, NULL );
998+ if (jpg_error != JPEG_ERROR_NONE) {
999+ mprintf ((" jpg: Couldn't open '%s'\n " , filename));
1000+ return -1 ;
1001+ }
1002+ }
1003+ // if its a pcx file
1004+ else if (type == BM_TYPE_PCX) {
1005+ int pcx_error = pcx_read_header (filename, img_cfp, w, h, bpp, NULL );
1006+ if (pcx_error != PCX_ERROR_NONE) {
1007+ mprintf ((" pcx: Couldn't open '%s'\n " , filename));
1008+ return -1 ;
1009+ }
1010+ }
1011+ else {
1012+ Assertion (false , " Unknown file type specified! This is probably a coding error." );
1013+
1014+ return -1 ;
1015+ }
1016+
1017+ return 0 ;
1018+ }
1019+
9161020int bm_load (const char *real_filename) {
9171021 int i, free_slot = -1 ;
9181022 int w, h, bpp = 8 ;
@@ -985,7 +1089,7 @@ int bm_load(const char *real_filename) {
9851089 goto Done;
9861090 }
9871091
988- rc = gr_bm_load (type, free_slot, filename, img_cfp, &w, &h, &bpp, &c_type, &mm_lvl, &bm_size);
1092+ rc = bm_load_info (type, free_slot, filename, img_cfp, &w, &h, &bpp, &c_type, &mm_lvl, &bm_size);
9891093
9901094 if (rc != 0 )
9911095 goto Done;
@@ -1111,6 +1215,109 @@ bool bm_load_and_parse_eff(const char *filename, int dir_type, int *nframes, int
11111215 return true ;
11121216}
11131217
1218+
1219+ /* *
1220+ * Lock an image files data into memory
1221+ */
1222+ static int bm_load_image_data (const char *filename, int handle, int bitmapnum, ubyte bpp, ubyte flags, bool nodebug)
1223+ {
1224+ BM_TYPE c_type = BM_TYPE_NONE;
1225+ ubyte true_bpp;
1226+
1227+ bitmap_entry *be = &bm_bitmaps[bitmapnum];
1228+ bitmap *bmp = &be->bm ;
1229+
1230+ Assert (!Is_standalone);
1231+
1232+ if (bmp->true_bpp > bpp)
1233+ true_bpp = bmp->true_bpp ;
1234+ else
1235+ true_bpp = bpp;
1236+
1237+ // don't do a bpp check here since it could be different in OGL - taylor
1238+ if (bmp->data == 0 ) {
1239+ Assert (be->ref_count == 1 );
1240+
1241+ if (be->type != BM_TYPE_USER && !nodebug) {
1242+ if (bmp->data == 0 )
1243+ nprintf ((" BmpMan" , " Loading %s for the first time.\n " , be->filename ));
1244+ }
1245+
1246+ if (!Bm_paging) {
1247+ if (be->type != BM_TYPE_USER && !nodebug)
1248+ nprintf ((" Paging" , " Loading %s (%dx%dx%d)\n " , be->filename , bmp->w , bmp->h , true_bpp));
1249+ }
1250+
1251+ // select proper format
1252+ if (flags & BMP_AABITMAP)
1253+ BM_SELECT_ALPHA_TEX_FORMAT ();
1254+ else if (flags & BMP_TEX_ANY)
1255+ BM_SELECT_TEX_FORMAT ();
1256+ else
1257+ BM_SELECT_SCREEN_FORMAT ();
1258+
1259+ // make sure we use the real graphic type for EFFs
1260+ if (be->type == BM_TYPE_EFF) {
1261+ c_type = be->info .ani .eff .type ;
1262+ }
1263+ else {
1264+ c_type = be->type ;
1265+ }
1266+
1267+ switch (c_type)
1268+ {
1269+ case BM_TYPE_PCX:
1270+ bm_lock_pcx (handle, bitmapnum, be, bmp, true_bpp, flags);
1271+ break ;
1272+
1273+ case BM_TYPE_ANI:
1274+ bm_lock_ani (handle, bitmapnum, be, bmp, true_bpp, flags);
1275+ break ;
1276+
1277+ case BM_TYPE_TGA:
1278+ bm_lock_tga (handle, bitmapnum, be, bmp, true_bpp, flags);
1279+ break ;
1280+
1281+ case BM_TYPE_PNG:
1282+ // libpng handles compression with zlib
1283+ bm_lock_png (handle, bitmapnum, be, bmp, true_bpp, flags);
1284+ break ;
1285+
1286+ case BM_TYPE_JPG:
1287+ bm_lock_jpg (handle, bitmapnum, be, bmp, true_bpp, flags);
1288+ break ;
1289+
1290+ case BM_TYPE_DDS:
1291+ case BM_TYPE_DXT1:
1292+ case BM_TYPE_DXT3:
1293+ case BM_TYPE_DXT5:
1294+ case BM_TYPE_CUBEMAP_DDS:
1295+ case BM_TYPE_CUBEMAP_DXT1:
1296+ case BM_TYPE_CUBEMAP_DXT3:
1297+ case BM_TYPE_CUBEMAP_DXT5:
1298+ bm_lock_dds (handle, bitmapnum, be, bmp, true_bpp, flags);
1299+ break ;
1300+
1301+ case BM_TYPE_USER:
1302+ bm_lock_user (handle, bitmapnum, be, bmp, true_bpp, flags);
1303+ break ;
1304+
1305+ default :
1306+ Warning (LOCATION, " Unsupported type in bm_lock -- %d\n " , c_type);
1307+ return -1 ;
1308+ }
1309+
1310+ // always go back to screen format
1311+ BM_SELECT_SCREEN_FORMAT ();
1312+
1313+ // make sure we actually did something
1314+ if (!(bmp->data ))
1315+ return -1 ;
1316+ }
1317+
1318+ return 0 ;
1319+ }
1320+
11141321int bm_load_animation (const char *real_filename, int *nframes, int *fps, int *keyframe, int can_drop_frames, int dir_type) {
11151322 int i, n;
11161323 anim the_anim;
@@ -1279,7 +1486,7 @@ int bm_load_animation(const char *real_filename, int *nframes, int *fps, int *ke
12791486 sprintf (bm_bitmaps[n + i].info .ani .eff .filename , " %s_%.4d" , clean_name, i);
12801487
12811488 // gr_bm_load() returns non-0 on failure
1282- if (gr_bm_load (eff_type, n + i, bm_bitmaps[n + i].info .ani .eff .filename , NULL , &anim_width, &anim_height, &bpp, &c_type, &mm_lvl, &img_size)) {
1489+ if (bm_load_info (eff_type, n + i, bm_bitmaps[n + i].info .ani .eff .filename , NULL , &anim_width, &anim_height, &bpp, &c_type, &mm_lvl, &img_size)) {
12831490 // if we didn't get anything then bail out now
12841491 if (i == 0 ) {
12851492 Warning (LOCATION, " EFF: No frame images were found. EFF, %s, is invalid.\n " , filename);
@@ -1504,13 +1711,21 @@ bitmap * bm_lock(int handle, ubyte bpp, ubyte flags, bool nodebug) {
15041711#endif
15051712
15061713 // read the file data
1507- if (gr_bm_lock (be->filename , handle, bitmapnum, bpp, flags, nodebug) == -1 ) {
1714+ if (bm_load_image_data (be->filename , handle, bitmapnum, bpp, flags, nodebug) == -1 ) {
15081715 // oops, this isn't good - reset and return NULL
15091716 bm_unlock ( handle );
15101717 bm_unload ( handle );
15111718
15121719 return NULL ;
15131720 }
1721+
1722+ if (!gr_bm_data (bitmapnum, bmp)) {
1723+ // graphics subsystem failed, reset and return NULL
1724+ bm_unlock ( handle );
1725+ bm_unload ( handle );
1726+
1727+ return NULL ;
1728+ }
15141729
15151730 MONITOR_INC (NumBitmapPage, 1 );
15161731 MONITOR_INC (SizeBitmapPage, bmp->w *bmp->h );
0 commit comments