Mercurial > hg > orthanc
comparison OrthancServer/Internals/DicomImageDecoder.cpp @ 863:3c0d0836f704 jpeg
refactoring
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Tue, 10 Jun 2014 17:20:33 +0200 |
parents | a546b05a43da |
children | 87791ebc1f50 |
comparison
equal
deleted
inserted
replaced
862:5a125d587810 | 863:3c0d0836f704 |
---|---|
40 (cf. function "DecodePsmctRle1()"): | 40 (cf. function "DecodePsmctRle1()"): |
41 | 41 |
42 Program: GDCM (Grassroots DICOM). A DICOM library | 42 Program: GDCM (Grassroots DICOM). A DICOM library |
43 Module: http://gdcm.sourceforge.net/Copyright.html | 43 Module: http://gdcm.sourceforge.net/Copyright.html |
44 | 44 |
45 Copyright (c) 2006-2011 Mathieu Malaterre | 45 Copyright (c) 2006-2011 Mathieu Malaterre |
46 Copyright (c) 1993-2005 CREATIS | 46 Copyright (c) 1993-2005 CREATIS |
47 (CREATIS = Centre de Recherche et d'Applications en Traitement de l'Image) | 47 (CREATIS = Centre de Recherche et d'Applications en Traitement de l'Image) |
48 All rights reserved. | 48 All rights reserved. |
49 | 49 |
50 Redistribution and use in source and binary forms, with or without | 50 Redistribution and use in source and binary forms, with or without |
51 modification, are permitted provided that the following conditions are met: | 51 modification, are permitted provided that the following conditions are met: |
52 | 52 |
53 * Redistributions of source code must retain the above copyright notice, | 53 * Redistributions of source code must retain the above copyright notice, |
54 this list of conditions and the following disclaimer. | 54 this list of conditions and the following disclaimer. |
55 | 55 |
56 * Redistributions in binary form must reproduce the above copyright notice, | 56 * Redistributions in binary form must reproduce the above copyright notice, |
57 this list of conditions and the following disclaimer in the documentation | 57 this list of conditions and the following disclaimer in the documentation |
58 and/or other materials provided with the distribution. | 58 and/or other materials provided with the distribution. |
59 | 59 |
60 * Neither name of Mathieu Malaterre, or CREATIS, nor the names of any | 60 * Neither name of Mathieu Malaterre, or CREATIS, nor the names of any |
61 contributors (CNRS, INSERM, UCB, Universite Lyon I), may be used to | 61 contributors (CNRS, INSERM, UCB, Universite Lyon I), may be used to |
62 endorse or promote products derived from this software without specific | 62 endorse or promote products derived from this software without specific |
63 prior written permission. | 63 prior written permission. |
64 | 64 |
65 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' | 65 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' |
66 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | 66 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
67 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | 67 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
68 ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR | 68 ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR |
69 ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | 69 ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
70 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR | 70 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR |
71 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER | 71 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER |
72 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, | 72 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, |
73 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 73 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
74 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 74 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
75 | 75 |
76 =========================================================================*/ | 76 =========================================================================*/ |
77 | 77 |
78 | 78 |
79 | 79 |
80 #include "../../Core/OrthancException.h" | 80 #include "../../Core/OrthancException.h" |
81 #include "../../Core/ImageFormats/ImageProcessing.h" | 81 #include "../../Core/ImageFormats/ImageProcessing.h" |
424 ImageAccessor targetAccessor(target.GetAccessor()); | 424 ImageAccessor targetAccessor(target.GetAccessor()); |
425 const DicomImageInformation& info = source.GetAccessor().GetInformation(); | 425 const DicomImageInformation& info = source.GetAccessor().GetInformation(); |
426 | 426 |
427 bool fastVersionSuccess = false; | 427 bool fastVersionSuccess = false; |
428 PixelFormat sourceFormat; | 428 PixelFormat sourceFormat; |
429 if (info.ExtractPixelFormat(sourceFormat)) | 429 if (!info.IsPlanar() && |
430 info.ExtractPixelFormat(sourceFormat)) | |
430 { | 431 { |
431 try | 432 try |
432 { | 433 { |
433 ImageAccessor sourceImage; | 434 ImageAccessor sourceImage; |
434 sourceImage.AssignReadOnly(sourceFormat, | 435 sourceImage.AssignReadOnly(sourceFormat, |
458 switch (target.GetFormat()) | 459 switch (target.GetFormat()) |
459 { | 460 { |
460 case PixelFormat_RGB24: | 461 case PixelFormat_RGB24: |
461 case PixelFormat_RGBA32: | 462 case PixelFormat_RGBA32: |
462 case PixelFormat_Grayscale8: | 463 case PixelFormat_Grayscale8: |
463 CopyPixels<uint8_t>(targetAccessor, source.GetAccessor()); | 464 CopyPixels<uint8_t>(targetAccessor, source.GetAccessor()); |
464 break; | 465 break; |
465 | 466 |
466 case PixelFormat_Grayscale16: | 467 case PixelFormat_Grayscale16: |
467 CopyPixels<uint16_t>(targetAccessor, source.GetAccessor()); | 468 CopyPixels<uint16_t>(targetAccessor, source.GetAccessor()); |
468 break; | 469 break; |
469 | 470 |
470 case PixelFormat_SignedGrayscale16: | 471 case PixelFormat_SignedGrayscale16: |
471 CopyPixels<int16_t>(targetAccessor, source.GetAccessor()); | 472 CopyPixels<int16_t>(targetAccessor, source.GetAccessor()); |
472 break; | 473 break; |
473 | 474 |
474 default: | 475 default: |
475 throw OrthancException(ErrorCode_InternalError); | 476 throw OrthancException(ErrorCode_InternalError); |
476 } | 477 } |
477 } | 478 } |
478 } | 479 } |
479 | 480 |
480 | 481 |
582 | 583 |
583 return false; | 584 return false; |
584 } | 585 } |
585 | 586 |
586 | 587 |
587 bool DicomImageDecoder::Decode(ImageBuffer& target, | 588 bool DicomImageDecoder::DecodeAndTruncate(ImageBuffer& target, |
588 DcmDataset& dataset, | 589 DcmDataset& dataset, |
589 unsigned int frame, | 590 unsigned int frame, |
590 PixelFormat format, | 591 PixelFormat format) |
591 Mode mode) | 592 { |
592 { | 593 // TODO Special case for uncompressed images |
593 // TODO OPTIMIZE THIS (avoid unnecessary image copies) !!! | 594 |
594 | 595 ImageBuffer source; |
595 ImageBuffer tmp; | 596 if (!Decode(source, dataset, frame)) |
596 if (!Decode(tmp, dataset, frame)) | |
597 { | 597 { |
598 return false; | 598 return false; |
599 } | 599 } |
600 | 600 |
601 if (!IsUncompressedImage(dataset) && !IsJpegLossless(dataset)) | 601 if (source.GetFormat() == format) |
602 { | 602 { |
603 printf("ICI\n"); | 603 // No conversion is required, return the temporary image |
604 PngWriter w; | 604 target.AcquireOwnership(source); |
605 ImageAccessor b(tmp.GetConstAccessor()); | 605 return true; |
606 w.WriteToFile("toto.png", b); | |
607 } | 606 } |
608 | 607 |
609 target.SetFormat(format); | 608 target.SetFormat(format); |
610 target.SetWidth(tmp.GetWidth()); | 609 target.SetWidth(source.GetWidth()); |
611 target.SetHeight(tmp.GetHeight()); | 610 target.SetHeight(source.GetHeight()); |
612 | 611 |
613 switch (mode) | 612 ImageAccessor targetAccessor(target.GetAccessor()); |
614 { | 613 ImageAccessor sourceAccessor(source.GetAccessor()); |
615 case Mode_Truncate: | 614 ImageProcessing::Convert(targetAccessor, sourceAccessor); |
616 { | 615 |
617 if (!IsUncompressedImage(dataset) && !IsJpegLossless(dataset)) | 616 return true; |
617 } | |
618 | |
619 | |
620 bool DicomImageDecoder::DecodePreview(ImageBuffer& target, | |
621 DcmDataset& dataset, | |
622 unsigned int frame) | |
623 { | |
624 // TODO Special case for uncompressed images | |
625 | |
626 ImageBuffer source; | |
627 if (!Decode(source, dataset, frame)) | |
628 { | |
629 return false; | |
630 } | |
631 | |
632 switch (source.GetFormat()) | |
633 { | |
634 case PixelFormat_RGB24: | |
635 { | |
636 // Directly return color images (RGB) | |
637 target.AcquireOwnership(source); | |
638 return true; | |
639 } | |
640 | |
641 case PixelFormat_Grayscale8: | |
642 case PixelFormat_Grayscale16: | |
643 case PixelFormat_SignedGrayscale16: | |
644 { | |
645 // Grayscale image: Stretch its dynamics to the [0,255] range | |
646 target.SetFormat(PixelFormat_Grayscale8); | |
647 target.SetWidth(source.GetWidth()); | |
648 target.SetHeight(source.GetHeight()); | |
649 | |
650 ImageAccessor targetAccessor(target.GetAccessor()); | |
651 ImageAccessor sourceAccessor(source.GetAccessor()); | |
652 | |
653 int64_t a, b; | |
654 ImageProcessing::GetMinMaxValue(a, b, sourceAccessor); | |
655 | |
656 if (a == b) | |
618 { | 657 { |
619 printf("%d => %d\n", tmp.GetFormat(), target.GetFormat()); | 658 ImageProcessing::Set(targetAccessor, 0); |
620 } | 659 } |
621 ImageAccessor a(target.GetAccessor()); | 660 else |
622 ImageAccessor b(tmp.GetConstAccessor()); | 661 { |
623 ImageProcessing::Convert(a, b); | 662 ImageProcessing::ShiftScale(sourceAccessor, -a, 255.0f / static_cast<float>(b - a)); |
663 | |
664 if (source.GetFormat() == PixelFormat_Grayscale8) | |
665 { | |
666 target.AcquireOwnership(source); | |
667 } | |
668 else | |
669 { | |
670 ImageProcessing::Convert(targetAccessor, sourceAccessor); | |
671 } | |
672 } | |
673 | |
624 return true; | 674 return true; |
625 } | 675 } |
626 | 676 |
627 default: | 677 default: |
628 throw OrthancException(ErrorCode_NotImplemented); | 678 throw OrthancException(ErrorCode_NotImplemented); |
629 } | 679 } |
630 | 680 } |
631 return false; | |
632 } | |
633 | |
634 | |
635 | |
636 } | 681 } |