Adding JPEG reading support
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 0bcf648..8f63db7 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -67,6 +67,7 @@
basisu_bc7enc.cpp
lodepng.cpp
apg_bmp.c
+ jpgd.cpp
transcoder/basisu_transcoder.cpp
)
diff --git a/basisu.vcxproj b/basisu.vcxproj
index c61c4a2..c23a715 100644
--- a/basisu.vcxproj
+++ b/basisu.vcxproj
@@ -154,6 +154,7 @@
<ClCompile Include="basisu_bc7enc.cpp" />
<ClCompile Include="basisu_ssim.cpp" />
<ClCompile Include="basisu_uastc_enc.cpp" />
+ <ClCompile Include="jpgd.cpp" />
<ClCompile Include="transcoder\basisu_transcoder.cpp" />
<ClInclude Include="apg_bmp.h" />
<ClInclude Include="basisu_bc7enc.h" />
@@ -173,6 +174,7 @@
<ClCompile Include="basisu_resample_filters.cpp" />
<ClInclude Include="basisu_ssim.h" />
<ClInclude Include="basisu_uastc_enc.h" />
+ <ClInclude Include="jpgd.h" />
<ClInclude Include="lodepng.h" />
<ClInclude Include="transcoder\basisu.h" />
<ClInclude Include="transcoder\basisu_transcoder.h" />
diff --git a/basisu.vcxproj.filters b/basisu.vcxproj.filters
index 218c3f1..1764b4b 100644
--- a/basisu.vcxproj.filters
+++ b/basisu.vcxproj.filters
@@ -22,6 +22,7 @@
<ClCompile Include="basisu_uastc_enc.cpp" />
<ClCompile Include="basisu_bc7enc.cpp" />
<ClCompile Include="apg_bmp.c" />
+ <ClCompile Include="jpgd.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="basisu_basis_file.h" />
@@ -58,6 +59,7 @@
<Filter>transcoder</Filter>
</ClInclude>
<ClInclude Include="apg_bmp.h" />
+ <ClInclude Include="jpgd.h" />
</ItemGroup>
<ItemGroup>
<None Include="transcoder\basisu_transcoder_tables_dxt1_6.inc">
diff --git a/basisu_enc.cpp b/basisu_enc.cpp
index a18bb36..488eaf2 100644
--- a/basisu_enc.cpp
+++ b/basisu_enc.cpp
@@ -20,6 +20,7 @@
#include "transcoder/basisu_transcoder.h"
#include "basisu_bc7enc.h"
#include "apg_bmp.h"
+#include "jpgd.h"
#if defined(_WIN32)
// For QueryPerformanceCounter/QueryPerformanceFrequency
@@ -229,7 +230,7 @@
return true;
}
-
+
bool load_tga(const char* pFilename, image& img)
{
int w = 0, h = 0, n_chans = 0;
@@ -326,6 +327,20 @@
return true;
}
+ bool load_jpg(const char *pFilename, image& img)
+ {
+ int width = 0, height = 0, actual_comps = 0;
+ uint8_t *pImage_data = jpgd::decompress_jpeg_image_from_file(pFilename, &width, &height, &actual_comps, 4, 0);
+ if (!pImage_data)
+ return false;
+
+ img.init(pImage_data, width, height, 4);
+
+ free(pImage_data);
+
+ return true;
+ }
+
bool load_image(const char* pFilename, image& img)
{
std::string ext(string_get_extension(std::string(pFilename)));
@@ -341,6 +356,8 @@
return load_bmp(pFilename, img);
if (strcasecmp(pExt, "tga") == 0)
return load_tga(pFilename, img);
+ if ( (strcasecmp(pExt, "jpg") == 0) || (strcasecmp(pExt, "jfif") == 0) || (strcasecmp(pExt, "jpeg") == 0) )
+ return load_jpg(pFilename, img);
return false;
}
@@ -1933,5 +1950,5 @@
return read_tga(&filedata[0], (uint32_t)filedata.size(), width, height, n_chans);
}
-
+
} // namespace basisu
diff --git a/basisu_enc.h b/basisu_enc.h
index 2267b95..b1abba0 100644
--- a/basisu_enc.h
+++ b/basisu_enc.h
@@ -132,6 +132,16 @@
return v;
}
+ inline uint32_t wang_hash(uint32_t seed)
+ {
+ seed = (seed ^ 61) ^ (seed >> 16);
+ seed *= 9;
+ seed = seed ^ (seed >> 4);
+ seed *= 0x27d4eb2d;
+ seed = seed ^ (seed >> 15);
+ return seed;
+ }
+
uint32_t hash_hsieh(const uint8_t* pBuf, size_t len);
template <typename Key>
@@ -2270,6 +2280,12 @@
resize(w, h, p);
}
+ image(const uint8_t *pImage, uint32_t width, uint32_t height, uint32_t comps) :
+ m_width(0), m_height(0), m_pitch(0)
+ {
+ init(pImage, width, height, comps);
+ }
+
image(const image &other) :
m_width(0), m_height(0), m_pitch(0)
{
@@ -2318,6 +2334,47 @@
return *this;
}
+ void init(const uint8_t *pImage, uint32_t width, uint32_t height, uint32_t comps)
+ {
+ assert(comps >= 1 && comps <= 4);
+
+ resize(width, height);
+
+ for (uint32_t y = 0; y < height; y++)
+ {
+ for (uint32_t x = 0; x < width; x++)
+ {
+ const uint8_t *pSrc = &pImage[(x + y * width) * comps];
+ color_rgba &dst = (*this)(x, y);
+
+ if (comps == 1)
+ {
+ dst.r = pSrc[0];
+ dst.g = pSrc[0];
+ dst.b = pSrc[0];
+ dst.a = 255;
+ }
+ else if (comps == 2)
+ {
+ dst.r = pSrc[0];
+ dst.g = pSrc[0];
+ dst.b = pSrc[0];
+ dst.a = pSrc[1];
+ }
+ else
+ {
+ dst.r = pSrc[0];
+ dst.g = pSrc[1];
+ dst.b = pSrc[2];
+ if (comps == 4)
+ dst.a = pSrc[3];
+ else
+ dst.a = 255;
+ }
+ }
+ }
+ }
+
image &fill_box(uint32_t x, uint32_t y, uint32_t w, uint32_t h, const color_rgba &c)
{
for (uint32_t iy = 0; iy < h; iy++)
@@ -2807,6 +2864,9 @@
bool load_tga(const char* pFilename, image& img);
inline bool load_tga(const std::string &filename, image &img) { return load_tga(filename.c_str(), img); }
+
+ bool load_jpg(const char *pFilename, image& img);
+ inline bool load_jpg(const std::string &filename, image &img) { return load_jpg(filename.c_str(), img); }
// Currently loads .BMP, .PNG, or .TGA.
bool load_image(const char* pFilename, image& img);
@@ -2814,7 +2874,7 @@
uint8_t *read_tga(const uint8_t *pBuf, uint32_t buf_size, int &width, int &height, int &n_chans);
uint8_t *read_tga(const char *pFilename, int &width, int &height, int &n_chans);
-
+
enum
{
cImageSaveGrayscale = 1,
diff --git a/basisu_tool.cpp b/basisu_tool.cpp
index b661693..813d08b 100644
--- a/basisu_tool.cpp
+++ b/basisu_tool.cpp
@@ -52,11 +52,11 @@
printf("\nUsage: basisu filename [filename ...] <options>\n");
puts("\n"
- "The default mode is compression of one or more PNG/BMP/TGA files to a .basis file. Alternate modes:\n"
+ "The default mode is compression of one or more PNG/BMP/TGA/JPG files to a .basis file. Alternate modes:\n"
" -unpack: Use transcoder to unpack .basis file to one or more .ktx/.png files\n"
" -validate: Validate and display information about a .basis file\n"
" -info: Display high-level information about a .basis file\n"
- " -compare: Compare two PNG/BMP/TGA images specified with -file, output PSNR and SSIM statistics and RGB/A delta images\n"
+ " -compare: Compare two PNG/BMP/TGA/JPG images specified with -file, output PSNR and SSIM statistics and RGB/A delta images\n"
" -version: Print basisu version and exit\n"
"Unless an explicit mode is specified, if one or more files have the .basis extension this tool defaults to unpack mode.\n"
"\n"
@@ -66,8 +66,8 @@
"Filenames prefixed with a @ symbol are read as filename listing files. Listing text files specify which actual filenames to process (one filename per line).\n"
"\n"
"Options:\n"
- " -file filename.png/bmp/tga: Input image filename, multiple images are OK, use -file X for each input filename (prefixing input filenames with -file is optional)\n"
- " -alpha_file filename.png/bmp/tga: Input alpha image filename, multiple images are OK, use -file X for each input filename (must be paired with -file), images converted to REC709 grayscale and used as input alpha\n"
+ " -file filename.png/bmp/tga/jpg: Input image filename, multiple images are OK, use -file X for each input filename (prefixing input filenames with -file is optional)\n"
+ " -alpha_file filename.png/bmp/tga/jpg: Input alpha image filename, multiple images are OK, use -file X for each input filename (must be paired with -file), images converted to REC709 grayscale and used as input alpha\n"
" -multifile_printf: printf() format strint to use to compose multiple filenames\n"
" -multifile_first: The index of the first file to process, default is 0 (must specify -multifile_printf and -multifile_num)\n"
" -multifile_num: The total number of files to process.\n"