# HG changeset patch # User Sebastien Jodogne # Date 1496175724 -7200 # Node ID 166a555becbf9cbfddb81c6665d6cee81b19f0a2 # Parent efd9ef2b67f1017c99ed9c858772630d3d629957 fix jpeg decoding in wasm diff -r efd9ef2b67f1 -r 166a555becbf Applications/Samples/SingleFrameApplication.h --- a/Applications/Samples/SingleFrameApplication.h Tue May 30 21:08:31 2017 +0200 +++ b/Applications/Samples/SingleFrameApplication.h Tue May 30 22:22:04 2017 +0200 @@ -155,9 +155,6 @@ Vector x; GeometryToolbox::AssignVector(x, cos(a), sin(a), 0); Vector y; GeometryToolbox::AssignVector(y, -sin(a), cos(a), 0); - GeometryToolbox::Print(source_->GetSlice(slice_).GetGeometry().GetOrigin()); - GeometryToolbox::Print(x); - GeometryToolbox::Print(y); SliceGeometry s(source_->GetSlice(slice_).GetGeometry().GetOrigin(), x, y); widget_->SetSlice(s); #endif @@ -247,6 +244,7 @@ #if 1 std::auto_ptr layer (new OrthancFrameLayerSource(context.GetWebService())); + //layer->SetImageQuality(SliceImageQuality_Jpeg50); layer->LoadInstance(instance, frame); //layer->LoadSeries("6f1b492a-e181e200-44e51840-ef8db55e-af529ab6"); layer->Register(*this); @@ -269,6 +267,7 @@ ct.reset(new OrthancFrameLayerSource(context.GetWebService())); //ct->LoadInstance("c804a1a2-142545c9-33b32fe2-3df4cec0-a2bea6d6", 0); //ct->LoadInstance("4bd4304f-47478948-71b24af2-51f4f1bc-275b6c1b", 0); // BAD SLICE + ct->SetImageQuality(SliceImageQuality_Jpeg50); ct->LoadSeries("dd069910-4f090474-7d2bba07-e5c10783-f9e4fb1d"); ct->Register(*this); diff -r efd9ef2b67f1 -r 166a555becbf Framework/Layers/OrthancFrameLayerSource.cpp --- a/Framework/Layers/OrthancFrameLayerSource.cpp Tue May 30 21:08:31 2017 +0200 +++ b/Framework/Layers/OrthancFrameLayerSource.cpp Tue May 30 22:22:04 2017 +0200 @@ -68,7 +68,8 @@ OrthancFrameLayerSource::OrthancFrameLayerSource(IWebService& orthanc) : - loader_(*this, orthanc) + loader_(*this, orthanc), + quality_(SliceImageQuality_Full) { } @@ -123,8 +124,7 @@ { if (loader_.LookupSlice(index, viewportSlice)) { - loader_.ScheduleLoadSliceImage(index, SliceImageQuality_Full); - //loader_.ScheduleLoadSliceImage(index, SliceImageQuality_Jpeg50); + loader_.ScheduleLoadSliceImage(index, quality_); } else { diff -r efd9ef2b67f1 -r 166a555becbf Framework/Layers/OrthancFrameLayerSource.h --- a/Framework/Layers/OrthancFrameLayerSource.h Tue May 30 21:08:31 2017 +0200 +++ b/Framework/Layers/OrthancFrameLayerSource.h Tue May 30 22:22:04 2017 +0200 @@ -32,7 +32,8 @@ private OrthancSlicesLoader::ICallback { private: - OrthancSlicesLoader loader_; + OrthancSlicesLoader loader_; + SliceImageQuality quality_; virtual void NotifyGeometryReady(const OrthancSlicesLoader& loader); @@ -57,6 +58,11 @@ void LoadSeries(const std::string& seriesId); + void SetImageQuality(SliceImageQuality quality) + { + quality_ = quality; + } + virtual size_t GetSliceCount() const { return loader_.GetSliceCount(); diff -r efd9ef2b67f1 -r 166a555becbf Framework/Toolbox/OrthancSlicesLoader.cpp --- a/Framework/Toolbox/OrthancSlicesLoader.cpp Tue May 30 21:08:31 2017 +0200 +++ b/Framework/Toolbox/OrthancSlicesLoader.cpp Tue May 30 22:22:04 2017 +0200 @@ -35,6 +35,36 @@ #include + + +/** + * TODO This is a SLOW implementation of base64 decoding, because + * "Orthanc::Toolbox::DecodeBase64()" does not work properly with + * WASM. UNDERSTAND WHY. + * https://stackoverflow.com/a/34571089/881731 + **/ +static std::string base64_decode(const std::string &in) +{ + std::string out; + + std::vector T(256,-1); + for (int i=0; i<64; i++) T["ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[i]] = i; + + int val=0, valb=-8; + for (unsigned char c : in) { + if (T[c] == -1) break; + val = (val<<6) + T[c]; + valb += 6; + if (valb>=0) { + out.push_back(char((val>>valb)&0xFF)); + valb-=8; + } + } + return out; +} + + + namespace OrthancStone { class OrthancSlicesLoader::Operation : public Orthanc::IDynamicObject @@ -348,9 +378,9 @@ } NotifySliceImageSuccess(operation, image); - } - - + } + + void OrthancSlicesLoader::ParseSliceImageJpeg(const Operation& operation, const void* answer, size_t size) @@ -394,20 +424,23 @@ } } - std::string jpeg; - Orthanc::Toolbox::DecodeBase64(jpeg, info["PixelData"].asString()); - std::auto_ptr reader; - try { - reader.reset(new Orthanc::JpegReader); - dynamic_cast(*reader).ReadFromMemory(jpeg); - } - catch (Orthanc::OrthancException&) - { - NotifySliceImageError(operation); - return; + std::string jpeg; + //Orthanc::Toolbox::DecodeBase64(jpeg, info["PixelData"].asString()); + jpeg = base64_decode(info["PixelData"].asString()); + + try + { + reader.reset(new Orthanc::JpegReader); + dynamic_cast(*reader).ReadFromMemory(jpeg); + } + catch (Orthanc::OrthancException&) + { + NotifySliceImageError(operation); + return; + } } Orthanc::PixelFormat expectedFormat =