comparison Core/Compression/ZlibCompressor.cpp @ 0:3959d33612cc

initial commit
author Sebastien Jodogne <s.jodogne@gmail.com>
date Thu, 19 Jul 2012 14:32:22 +0200
parents
children a15e90e5d6fc
comparison
equal deleted inserted replaced
-1:000000000000 0:3959d33612cc
1 /**
2 * Palantir - A Lightweight, RESTful DICOM Store
3 * Copyright (C) 2012 Medical Physics Department, CHU of Liege,
4 * Belgium
5 *
6 * This program is free software: you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation, either version 3 of the
9 * License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 **/
19
20
21 #include "ZlibCompressor.h"
22
23 #include <stdio.h>
24 #include <string.h>
25 #include <zlib.h>
26 #include "../PalantirException.h"
27
28 namespace Palantir
29 {
30 void ZlibCompressor::SetCompressionLevel(uint8_t level)
31 {
32 if (level >= 10)
33 {
34 throw PalantirException("Zlib compression level must be between 0 (no compression) and 9 (highest compression");
35 }
36 }
37
38
39 void ZlibCompressor::Compress(std::string& compressed,
40 const void* uncompressed,
41 size_t uncompressedSize)
42 {
43 if (uncompressedSize == 0)
44 {
45 compressed.clear();
46 return;
47 }
48
49 uLongf compressedSize = compressBound(uncompressedSize);
50 compressed.resize(compressedSize + sizeof(size_t));
51
52 int error = compress2
53 (reinterpret_cast<uint8_t*>(&compressed[0]) + sizeof(size_t),
54 &compressedSize,
55 const_cast<Bytef *>(static_cast<const Bytef *>(uncompressed)),
56 uncompressedSize,
57 compressionLevel_);
58
59 memcpy(&compressed[0], &uncompressedSize, sizeof(size_t));
60
61 if (error == Z_OK)
62 {
63 compressed.resize(compressedSize + sizeof(size_t));
64 return;
65 }
66 else
67 {
68 compressed.clear();
69
70 switch (error)
71 {
72 case Z_MEM_ERROR:
73 throw PalantirException(ErrorCode_NotEnoughMemory);
74
75 default:
76 throw PalantirException(ErrorCode_InternalError);
77 }
78 }
79 }
80
81
82 void ZlibCompressor::Uncompress(std::string& uncompressed,
83 const void* compressed,
84 size_t compressedSize)
85 {
86 if (compressedSize == 0)
87 {
88 uncompressed.clear();
89 return;
90 }
91
92 if (compressedSize < sizeof(size_t))
93 {
94 throw PalantirException("Zlib: The compressed buffer is ill-formed");
95 }
96
97 size_t uncompressedLength;
98 memcpy(&uncompressedLength, compressed, sizeof(size_t));
99 uncompressed.resize(uncompressedLength);
100
101 uLongf tmp = uncompressedLength;
102 int error = uncompress
103 (reinterpret_cast<uint8_t*>(&uncompressed[0]),
104 &tmp,
105 reinterpret_cast<const uint8_t*>(compressed) + sizeof(size_t),
106 compressedSize - sizeof(size_t));
107
108 if (error != Z_OK)
109 {
110 uncompressed.clear();
111
112 switch (error)
113 {
114 case Z_DATA_ERROR:
115 throw PalantirException("Zlib: Corrupted or incomplete compressed buffer");
116
117 case Z_MEM_ERROR:
118 throw PalantirException(ErrorCode_NotEnoughMemory);
119
120 default:
121 throw PalantirException(ErrorCode_InternalError);
122 }
123 }
124 }
125 }