diff --git a/imageformats/jpegencoder.cpp b/imageformats/jpegencoder.cpp
index 5d97ebc..1b97b89 100644
--- a/imageformats/jpegencoder.cpp
+++ b/imageformats/jpegencoder.cpp
@@ -23,6 +23,14 @@ along with this program. If not, see .
#include
#include
+#if __APPLE__
+#include
+#elif __FreeBSD__
+#include
+#else
+#include
+#endif
+
static_assert(BITS_IN_JSAMPLE == 8,
"libjpeg must have been compiled with BITS_IN_JSAMPLE = 8");
@@ -167,7 +175,7 @@ JpegEncoder::qualityPercent() const
void
JpegEncoder::onImageBegin()
{
- if (bitDepth() != BITS_IN_JSAMPLE)
+ if (bitDepth() != 8 && bitDepth() != 16)
throw std::runtime_error("JpegEncoder: bit depth unsupported");
if (currentImage() > 0)
throw std::runtime_error("JpegEncoder: cannot encode more than one image per file");
@@ -218,7 +226,23 @@ JpegEncoder::onImageEnd()
void
JpegEncoder::onWriteLine(const void* data)
{
- auto linedata = JSAMPROW(data);
+ std::vector line(width() * components());
+ if (bitDepth() == 16) {
+ union { const void* p; const unsigned short* s; const unsigned char* c; } p = { data };
+#if BYTE_ORDER == LITTLE_ENDIAN
+ const int idx = 1;
+#else
+ const int idx = 0;
+#endif
+ for (int i = 0; i < line.size(); ++i) {
+ line[i] = p.c[idx];
+ ++p.s;
+ }
+ }
+ else if (bitDepth() == 8) {
+ ::memcpy(line.data(), data, line.size());
+ }
+ auto linedata = JSAMPROW(line.data());
int written = ::jpeg_write_scanlines(&p->mCompressStruct, &linedata, 1);
if (written != 1)
throw std::runtime_error("JpegEncoder: could not write scan line");