1 //
2 // (C) Jan de Vaan 2007-2010, all rights reserved. See the accompanying "License.txt" for licensed use.
3 //
4 
5 
6 #include "config.h"
7 #include "util.h"
8 #include "intrface.h"
9 #include "header.h"
10 
11 
CheckInput(const void * compressedData,size_t compressedLength,const void * uncompressedData,size_t uncompressedLength,const JlsParameters * pparams)12 JLS_ERROR CheckInput(const void* compressedData, size_t compressedLength, const void* uncompressedData, size_t uncompressedLength, const JlsParameters* pparams)
13 {
14 	if (pparams == NULL)
15 		return InvalidJlsParameters;
16 
17 	if (compressedLength == 0)
18 		return InvalidJlsParameters;
19 
20 	if (compressedData == NULL)
21 		return InvalidJlsParameters;
22 
23 	if (uncompressedData == NULL)
24 		return InvalidJlsParameters;
25 
26 	if (pparams->width < 1 || pparams->width > 65535)
27 		return ParameterValueNotSupported;
28 
29 	if (pparams->height < 1 || pparams->height > 65535)
30 		return ParameterValueNotSupported;
31 
32 	int bytesperline = pparams->bytesperline < 0 ? -pparams->bytesperline : pparams->bytesperline;
33 
34 	if (uncompressedLength < size_t(bytesperline * pparams->height))
35 		return InvalidJlsParameters;
36 
37 	return CheckParameterCoherent(pparams);
38 }
39 
CheckInput(const void * uncompressedData,size_t uncompressedLength,const JlsParameters * pparams)40 JLS_ERROR CheckInput(const void* uncompressedData, size_t uncompressedLength, const JlsParameters* pparams)
41 {
42 	if (pparams == NULL)
43 		return InvalidJlsParameters;
44 
45 	if (uncompressedData == NULL)
46 		return InvalidJlsParameters;
47 
48 	if (pparams->width < 1 || pparams->width > 65535)
49 		return ParameterValueNotSupported;
50 
51 	if (pparams->height < 1 || pparams->height > 65535)
52 		return ParameterValueNotSupported;
53 
54 	int bytesperline = pparams->bytesperline < 0 ? -pparams->bytesperline : pparams->bytesperline;
55 
56 	if (uncompressedLength < size_t(bytesperline * pparams->height))
57 		return InvalidJlsParameters;
58 
59 	return CheckParameterCoherent(pparams);
60 }
61 
62 
63 
64 extern "C"
65 {
66 
JpegLsEncode(BYTE ** buf,size_t * buf_size,size_t * pcbyteWritten,const void * uncompressedData,size_t uncompressedLength,struct JlsParameters * pparams)67 CHARLS_IMEXPORT(JLS_ERROR) JpegLsEncode(BYTE **buf, size_t *buf_size, size_t* pcbyteWritten, const void* uncompressedData, size_t uncompressedLength, struct JlsParameters* pparams)
68 {
69 	*pcbyteWritten = 0;
70 
71 	JlsParameters info = *pparams;
72 	if(info.bytesperline == 0)
73 	{
74 		info.bytesperline = info.width * ((info.bitspersample + 7)/8);
75 		if (info.ilv != ILV_NONE)
76 		{
77 			info.bytesperline *= info.components;
78 		}
79 	}
80 
81 	JLS_ERROR parameterError = CheckInput(uncompressedData, uncompressedLength, &info);
82 
83 	if (parameterError != OK)
84 		return parameterError;
85 
86 	if (pcbyteWritten == NULL)
87 		return InvalidJlsParameters;
88 
89 	Size size = Size(info.width, info.height);
90 	JLSOutputStream stream;
91 
92 	stream.Init(size, info.bitspersample, info.components);
93 
94 	if (info.colorTransform != 0)
95 	{
96 		stream.AddColorTransform(info.colorTransform);
97 	}
98 
99 	if (info.ilv == ILV_NONE)
100 	{
101 		LONG cbyteComp = size.cx*size.cy*((info.bitspersample +7)/8);
102 		for (LONG component = 0; component < info.components; ++component)
103 		{
104 			const BYTE* compareData = static_cast<const BYTE*>(uncompressedData) + component*cbyteComp;
105 			stream.AddScan(compareData, &info);
106 		}
107 	}
108 	else
109 	{
110 		stream.AddScan(uncompressedData, &info);
111 	}
112 
113 	try
114 	{
115 		stream.Write(buf, buf_size, 0);
116 	}
117 	catch (const alloc_fail&)
118 	{
119 		return MemoryAllocationFailure;
120 	}
121 
122 	*pcbyteWritten = stream.GetBytesWritten();
123 	return OK;
124 }
125 
JpegLsDecode(void * uncompressedData,size_t uncompressedLength,const void * compressedData,size_t compressedLength,JlsParameters * info)126 CHARLS_IMEXPORT(JLS_ERROR) JpegLsDecode(void* uncompressedData, size_t uncompressedLength, const void* compressedData, size_t compressedLength, JlsParameters* info)
127 {
128 	JLSInputStream reader((BYTE*)compressedData, compressedLength);
129 
130 	if(info != NULL)
131 	{
132 	 	reader.SetInfo(info);
133 	}
134 
135 	try
136 	{
137 		reader.Read(uncompressedData, uncompressedLength);
138 		return OK;
139 	}
140 	catch (JlsException& e)
141 	{
142 		return e._error;
143 	}
144 }
145 
146 
JpegLsDecodeRect(void * uncompressedData,size_t uncompressedLength,const void * compressedData,size_t compressedLength,JlsRect roi,JlsParameters * info)147 CHARLS_IMEXPORT(JLS_ERROR) JpegLsDecodeRect(void* uncompressedData, size_t uncompressedLength, const void* compressedData, size_t compressedLength, JlsRect roi, JlsParameters* info)
148 {
149 	JLSInputStream reader((BYTE*)compressedData, compressedLength);
150 
151 	if(info != NULL)
152 	{
153 	 	reader.SetInfo(info);
154 	}
155 
156 	reader.SetRect(roi);
157 
158 	try
159 	{
160 		reader.Read(uncompressedData, uncompressedLength);
161 		return OK;
162 	}
163 	catch (JlsException& e)
164 	{
165 		return e._error;
166 	}
167 }
168 
169 
JpegLsVerifyEncode(const void * uncompressedData,size_t uncompressedLength,const void * compressedData,size_t compressedLength)170 CHARLS_IMEXPORT(JLS_ERROR) JpegLsVerifyEncode(const void* uncompressedData, size_t uncompressedLength, const void* compressedData, size_t compressedLength)
171 {
172 	JlsParameters info = JlsParameters();
173 
174 	JLS_ERROR error = JpegLsReadHeader(compressedData, compressedLength, &info);
175 	if (error != OK)
176 		return error;
177 
178 	error = CheckInput(compressedData, compressedLength, uncompressedData, uncompressedLength, &info);
179 
180 	if (error != OK)
181 		return error;
182 
183 	Size size = Size(info.width, info.height);
184 
185 	JLSOutputStream stream;
186 
187 	stream.Init(size, info.bitspersample, info.components);
188 
189 	if (info.ilv == ILV_NONE)
190 	{
191 		LONG cbyteComp = size.cx*size.cy*((info.bitspersample +7)/8);
192 		for (LONG component = 0; component < info.components; ++component)
193 		{
194 			const BYTE* compareData = static_cast<const BYTE*>(uncompressedData) + component*cbyteComp;
195 			stream.AddScan(compareData, &info);
196 		}
197 	}
198 	else
199 	{
200 		stream.AddScan(uncompressedData, &info);
201 	}
202 
203 	size_t buf_size = compressedLength + 16;
204 	BYTE *buf = new BYTE[buf_size];
205 
206 	memcpy(buf, compressedData, compressedLength);
207 
208 	stream.EnableCompare(true);
209 
210 	try
211 	{
212 		stream.Write(&buf, &buf_size, 0);
213 	}
214 	catch (const alloc_fail&)
215 	{
216 		return MemoryAllocationFailure;
217 	}
218 
219 	return OK;
220 }
221 
222 
JpegLsReadHeader(const void * compressedData,size_t compressedLength,JlsParameters * pparams)223 CHARLS_IMEXPORT(JLS_ERROR) JpegLsReadHeader(const void* compressedData, size_t compressedLength, JlsParameters* pparams)
224 {
225 	try
226 	{
227 		JLSInputStream reader((BYTE*)compressedData, compressedLength);
228 		reader.ReadHeader();
229 		JlsParameters info = reader.GetMetadata();
230 		*pparams = info;
231 		return OK;
232 	}
233 	catch (JlsException& e)
234 	{
235 		return e._error;
236 	}
237 
238 }
239 
240 }
241