@@ -35,69 +35,49 @@ image_c::image_c(IConsole* conHnd)
3535 : con(conHnd)
3636{}
3737
38- void image_c::CopyRaw (int inType , dword inWidth, dword inHeight, const byte* inDat)
38+ bool image_c::CopyRaw (int type , dword inWidth, dword inHeight, const byte* inDat)
3939{
40- // Populate legacy fields
41- comp = inType & 0xF ;
42- type = inType;
43- width = inWidth;
44- height = inHeight;
45-
46- // Populate gli texture
47- PopulateTex (inDat);
48- }
40+ gli::format format = gli::format::FORMAT_UNDEFINED ;
41+ const glm::ivec2 extent{ inWidth, inHeight };
42+ if (type == IMGTYPE_NONE )
43+ tex = {};
44+
45+ if (type > IMGTYPE_RGBA )
46+ return false ;
4947
50- void image_c::Free ()
51- {
52- tex = {};
53- }
48+ if (inWidth >= (1 << 15 ) || inHeight >= (1 << 15 ))
49+ return false ;
5450
55- // TODO(zao): Make this function only care about unpacked source data.
56- void image_c::PopulateTex (const byte* dat)
57- {
58- gli::format format = gli::format::FORMAT_UNDEFINED ;
59- const glm::ivec2 extent{ width, height };
60- size_t dataSize = width * height * comp; // Common default for regular formats.
61-
62- const auto PhysicalSize = [](dword width, dword height, dword blockSize, dword side = 4 ) -> dword {
63- dword numBlocks = ((width + side - 1 ) / side) * ((height + side - 1 ) / side);
64- return numBlocks * blockSize;
65- };
66- switch ((imageType_s)type) {
67- case imageType_s::IMGTYPE_NONE :
51+ const int comp = type & 0xF ;
52+ size_t dataSize = extent.x * extent.y * comp;
53+
54+ switch (comp) {
55+ case 0 :
6856 tex = {};
69- return ;
70- case imageType_s::IMGTYPE_GRAY :
71- format = gli::format::FORMAT_R8_SRGB_PACK8 ;
72- break ;
73- case imageType_s::IMGTYPE_RGB :
74- format = gli::format::FORMAT_RGB8_SRGB_PACK8 ;
75- break ;
76- case imageType_s::IMGTYPE_RGBA :
77- format = gli::format::FORMAT_RGBA8_SNORM_PACK8 ;
78- break ;
79- case imageType_s::IMGTYPE_RGBA_BC1 :
80- format = gli::format::FORMAT_RGBA_DXT1_SRGB_BLOCK8 ;
81- dataSize = PhysicalSize (width, height, 8 );
57+ return false ;
58+ case 1 :
59+ format = gli::format::FORMAT_L8_UNORM_PACK8 ;
8260 break ;
83- case imageType_s::IMGTYPE_RGBA_BC2 :
84- format = gli::format::FORMAT_RGBA_DXT3_SRGB_BLOCK16 ;
85- dataSize = PhysicalSize (width, height, 16 );
61+ case 3 :
62+ format = gli::format::FORMAT_RGB8_UNORM_PACK8 ;
8663 break ;
87- case imageType_s::IMGTYPE_RGBA_BC3 :
88- format = gli::format::FORMAT_RGBA_DXT5_SRGB_BLOCK16 ;
89- dataSize = PhysicalSize (width, height, 16 );
64+ case 4 :
65+ format = gli::format::FORMAT_RGBA8_UNORM_PACK8 ;
9066 break ;
91- case imageType_s::IMGTYPE_RGBA_BC7 :
92- format = gli::format::FORMAT_RGBA_BP_SRGB_BLOCK16 ;
93- dataSize = PhysicalSize (width, height, 16 );
67+ default :
68+ return false ;
9469 }
95-
96- tex = gli::texture2d (format, extent, 1 );
70+ tex = gli::texture2d_array (format, extent, 1 , 1 );
9771 if (tex.size (0 ) == dataSize)
98- memcpy (tex.data (0 , 0 , 0 ), dat , dataSize);
72+ memcpy (tex.data (0 , 0 , 0 ), inDat , dataSize);
9973 else
10074 assert (tex.size (0 ) == dataSize);
75+ return true ;
76+ }
77+
78+ void image_c::Free ()
79+ {
80+ tex = {};
10181}
10282
10383bool image_c::Load (const char * fileName, std::optional<size_callback_t > sizeCallback)
@@ -202,10 +182,10 @@ bool targa_c::Load(const char* fileName, std::optional<size_callback_t> sizeCall
202182 }
203183
204184 // Read image
205- width = hdr.width ;
206- height = hdr.height ;
207- comp = hdr.depth >> 3 ;
208- type = ittable[it_m][2 ];
185+ dword width = hdr.width ;
186+ dword height = hdr.height ;
187+ int comp = hdr.depth >> 3 ;
188+ int type = ittable[it_m][2 ];
209189 int rowSize = width * comp;
210190 std::vector<byte> datBuf (height * rowSize);
211191 byte* dat = datBuf.data ();
@@ -253,30 +233,30 @@ bool targa_c::Load(const char* fileName, std::optional<size_callback_t> sizeCall
253233 }
254234 }
255235
256- PopulateTex (dat);
257-
258- return false ;
236+ return !CopyRaw (type, width, height, dat);
259237}
260238
261239bool targa_c::Save (const char * fileName)
262240{
263- if (type != IMGTYPE_RGB && type != IMGTYPE_RGBA ) {
241+ auto format = tex.format ();
242+ if (is_compressed (format) || !is_unsigned_integer (format))
243+ return true ;
244+
245+ int comp = (int )component_count (format);
246+ if (comp != 3 && comp != 4 )
264247 return true ;
265- }
266248
267249 // Open file
268250 fileOutputStream_c out;
269251 if (out.FileOpen (fileName, true )) {
270252 return true ;
271253 }
272254
273- if (is_compressed (tex.format ()))
274- return true ;
275-
255+ auto extent = tex.extent ();
276256 auto rc = stbi_write_tga_to_func ([](void * ctx, void * data, int size) {
277257 auto out = (fileOutputStream_c*)ctx;
278258 out->Write (data, size);
279- }, &out, width, height , comp, tex.data (0 , 0 , 0 ));
259+ }, &out, extent. x , extent. y , comp, tex.data (0 , 0 , 0 ));
280260
281261 return !rc;
282262}
@@ -304,7 +284,7 @@ bool jpeg_c::Load(const char* fileName, std::optional<size_callback_t> sizeCallb
304284 return true ;
305285 }
306286 if (in_comp != 1 && in_comp != 3 ) {
307- con->Warning (" JPEG '%s': unsupported component count '%d'" , fileName, comp );
287+ con->Warning (" JPEG '%s': unsupported component count '%d'" , fileName, in_comp );
308288 return true ;
309289 }
310290 if (sizeCallback)
@@ -315,37 +295,35 @@ bool jpeg_c::Load(const char* fileName, std::optional<size_callback_t> sizeCallb
315295 stbi_image_free (data);
316296 return true ;
317297 }
318- width = x;
319- height = y;
320- comp = in_comp;
321- type = in_comp == 1 ? IMGTYPE_GRAY : IMGTYPE_RGB ;
322298
323- PopulateTex ( data);
299+ bool success = CopyRaw (in_comp == 1 ? IMGTYPE_GRAY : IMGTYPE_RGB , x, y, data);
324300 stbi_image_free (data);
325301
326- return false ;
302+ return !success ;
327303}
328304
329305bool jpeg_c::Save (const char * fileName)
330306{
331307 // JPEG only supports RGB and grayscale images
332- if (type != IMGTYPE_RGB && type != IMGTYPE_GRAY ) {
308+ auto format = tex.format ();
309+ if (is_compressed (format) || !is_unsigned_integer (format))
310+ return true ;
311+
312+ int comp = (int )component_count (format);
313+ if (comp != 1 && comp != 3 )
333314 return true ;
334- }
335315
336316 // Open the file
337317 fileOutputStream_c out;
338318 if (out.FileOpen (fileName, true )) {
339319 return true ;
340320 }
341321
342- if (is_compressed (tex.format ()))
343- return true ;
344-
322+ auto extent = tex.extent ();
345323 int rc = stbi_write_jpg_to_func ([](void * ctx, void * data, int size) {
346324 auto out = (fileOutputStream_c*)ctx;
347325 out->Write (data, size);
348- }, &out, width, height , comp, tex.data (0 , 0 , 0 ), quality);
326+ }, &out, extent. x , extent. y , comp, tex.data (0 , 0 , 0 ), quality);
349327 return !rc;
350328}
351329
@@ -372,41 +350,46 @@ bool png_c::Load(const char* fileName, std::optional<size_callback_t> sizeCallba
372350 return true ;
373351 }
374352
375- width = x;
376- height = y;
353+ dword width = x;
354+ dword height = y;
377355 if (sizeCallback)
378356 (*sizeCallback)(width, height);
379357
380- comp = (in_comp == 1 || in_comp == 3 ) ? 3 : 4 ;
381- type = comp == 3 ? IMGTYPE_RGB : IMGTYPE_RGBA ;
358+ int comp = (in_comp == 1 || in_comp == 3 ) ? 3 : 4 ;
359+ int type = comp == 3 ? IMGTYPE_RGB : IMGTYPE_RGBA ;
382360 stbi_uc* data = stbi_load_from_memory (fileData.data (), (int )fileData.size (), &x, &y, &in_comp, comp);
383361 if (!data) {
384362 stbi_image_free (data);
385363 return true ;
386364 }
387365
388- PopulateTex ( data);
366+ bool success = CopyRaw (type, width, height, data);
389367 stbi_image_free (data);
390368
391- return false ;
369+ return !success ;
392370}
393371
394372bool png_c::Save (const char * fileName)
395373{
396- if (type != IMGTYPE_RGB && type != IMGTYPE_RGBA ) {
374+ auto format = tex.format ();
375+ if (is_compressed (format) || !is_unsigned_integer (format))
376+ return true ;
377+
378+ int comp = (int )component_count (format);
379+ if (comp != 3 && comp != 4 )
397380 return true ;
398- }
399381
400382 // Open file
401383 fileOutputStream_c out;
402384 if (out.FileOpen (fileName, true )) {
403385 return true ;
404386 }
405387
388+ auto extent = tex.extent ();
406389 auto rc = stbi_write_png_to_func ([](void * ctx, void * data, int size) {
407390 auto out = (fileOutputStream_c*)ctx;
408391 out->Write (data, size);
409- }, &out, width, height , comp, tex.data (0 , 0 , 0 ), width * comp);
392+ }, &out, extent. x , extent. y , comp, tex.data (0 , 0 , 0 ), extent. x * comp);
410393
411394 return !rc;
412395}
@@ -434,18 +417,15 @@ bool gif_c::Load(const char* fileName, std::optional<size_callback_t> sizeCallba
434417 stbi_image_free (data);
435418 return true ;
436419 }
437- width = x;
438- height = y;
420+ dword width = x;
421+ dword height = y;
439422 if (sizeCallback)
440423 (*sizeCallback)(width, height);
441424
442- comp = in_comp;
443- type = IMGTYPE_RGBA ;
444-
445- PopulateTex (data);
425+ bool success = CopyRaw (IMGTYPE_RGBA , width, height, data);
446426 stbi_image_free (data);
447427
448- return false ;
428+ return !success ;
449429 }
450430}
451431
@@ -490,6 +470,9 @@ bool jpeg_xl_c::Load(const char* fileName, std::optional<size_callback_t> sizeCa
490470 JxlDecoderCloseInput (dec.get ());
491471
492472 std::vector<byte> datBuf;
473+ int width{};
474+ int height{};
475+ int comp{};
493476
494477 while (true ) {
495478 JxlDecoderStatus status = JxlDecoderProcessInput (dec.get ());
@@ -507,13 +490,7 @@ bool jpeg_xl_c::Load(const char* fileName, std::optional<size_callback_t> sizeCa
507490 if (sizeCallback)
508491 (*sizeCallback)(width, height);
509492 comp = info.num_color_channels + !!info.alpha_bits ;
510- if (comp == 1 )
511- type = IMGTYPE_GRAY ;
512- else if (comp == 3 )
513- type = IMGTYPE_RGB ;
514- else if (comp == 4 )
515- type = IMGTYPE_RGBA ;
516- else
493+ if (comp != 1 && comp != 3 && comp != 4 )
517494 return true ;
518495
519496 if (runner)
@@ -535,8 +512,7 @@ bool jpeg_xl_c::Load(const char* fileName, std::optional<size_callback_t> sizeCa
535512 case JXL_DEC_SUCCESS :
536513 case JXL_DEC_FULL_IMAGE : {
537514 // We don't care about animations, consider loading completed when a full image has obtained.
538- PopulateTex (datBuf.data ());
539- return false ;
515+ return !CopyRaw (g_imageTypeFromComp[comp], width, height, datBuf.data ());
540516 } break ;
541517
542518 default :
0 commit comments