goat3d

annotate libs/openctm/stream.c @ 88:7941e89798e5

selections
author John Tsiombikas <nuclear@member.fsf.org>
date Thu, 15 May 2014 06:52:01 +0300
parents
children 21319e71117f
rev   line source
nuclear@14 1 //-----------------------------------------------------------------------------
nuclear@14 2 // Product: OpenCTM
nuclear@14 3 // File: stream.c
nuclear@14 4 // Description: Stream I/O functions.
nuclear@14 5 //-----------------------------------------------------------------------------
nuclear@14 6 // Copyright (c) 2009-2010 Marcus Geelnard
nuclear@14 7 //
nuclear@14 8 // This software is provided 'as-is', without any express or implied
nuclear@14 9 // warranty. In no event will the authors be held liable for any damages
nuclear@14 10 // arising from the use of this software.
nuclear@14 11 //
nuclear@14 12 // Permission is granted to anyone to use this software for any purpose,
nuclear@14 13 // including commercial applications, and to alter it and redistribute it
nuclear@14 14 // freely, subject to the following restrictions:
nuclear@14 15 //
nuclear@14 16 // 1. The origin of this software must not be misrepresented; you must not
nuclear@14 17 // claim that you wrote the original software. If you use this software
nuclear@14 18 // in a product, an acknowledgment in the product documentation would be
nuclear@14 19 // appreciated but is not required.
nuclear@14 20 //
nuclear@14 21 // 2. Altered source versions must be plainly marked as such, and must not
nuclear@14 22 // be misrepresented as being the original software.
nuclear@14 23 //
nuclear@14 24 // 3. This notice may not be removed or altered from any source
nuclear@14 25 // distribution.
nuclear@14 26 //-----------------------------------------------------------------------------
nuclear@14 27
nuclear@14 28 #include <stdlib.h>
nuclear@14 29 #include <string.h>
nuclear@14 30 #include <LzmaLib.h>
nuclear@14 31 #include "openctm.h"
nuclear@14 32 #include "internal.h"
nuclear@14 33
nuclear@14 34 #ifdef __DEBUG_
nuclear@14 35 #include <stdio.h>
nuclear@14 36 #endif
nuclear@14 37
nuclear@14 38 //-----------------------------------------------------------------------------
nuclear@14 39 // _ctmStreamRead() - Read data from a stream.
nuclear@14 40 //-----------------------------------------------------------------------------
nuclear@14 41 CTMuint _ctmStreamRead(_CTMcontext * self, void * aBuf, CTMuint aCount)
nuclear@14 42 {
nuclear@14 43 if(!self->mUserData || !self->mReadFn)
nuclear@14 44 return 0;
nuclear@14 45
nuclear@14 46 return self->mReadFn(aBuf, aCount, self->mUserData);
nuclear@14 47 }
nuclear@14 48
nuclear@14 49 //-----------------------------------------------------------------------------
nuclear@14 50 // _ctmStreamWrite() - Write data to a stream.
nuclear@14 51 //-----------------------------------------------------------------------------
nuclear@14 52 CTMuint _ctmStreamWrite(_CTMcontext * self, void * aBuf, CTMuint aCount)
nuclear@14 53 {
nuclear@14 54 if(!self->mUserData || !self->mWriteFn)
nuclear@14 55 return 0;
nuclear@14 56
nuclear@14 57 return self->mWriteFn(aBuf, aCount, self->mUserData);
nuclear@14 58 }
nuclear@14 59
nuclear@14 60 //-----------------------------------------------------------------------------
nuclear@14 61 // _ctmStreamReadUINT() - Read an unsigned integer from a stream in a machine
nuclear@14 62 // endian independent manner (for portability).
nuclear@14 63 //-----------------------------------------------------------------------------
nuclear@14 64 CTMuint _ctmStreamReadUINT(_CTMcontext * self)
nuclear@14 65 {
nuclear@14 66 unsigned char buf[4];
nuclear@14 67 _ctmStreamRead(self, (void *) buf, 4);
nuclear@14 68 return ((CTMuint) buf[0]) |
nuclear@14 69 (((CTMuint) buf[1]) << 8) |
nuclear@14 70 (((CTMuint) buf[2]) << 16) |
nuclear@14 71 (((CTMuint) buf[3]) << 24);
nuclear@14 72 }
nuclear@14 73
nuclear@14 74 //-----------------------------------------------------------------------------
nuclear@14 75 // _ctmStreamWriteUINT() - Write an unsigned integer to a stream in a machine
nuclear@14 76 // endian independent manner (for portability).
nuclear@14 77 //-----------------------------------------------------------------------------
nuclear@14 78 void _ctmStreamWriteUINT(_CTMcontext * self, CTMuint aValue)
nuclear@14 79 {
nuclear@14 80 unsigned char buf[4];
nuclear@14 81 buf[0] = aValue & 0x000000ff;
nuclear@14 82 buf[1] = (aValue >> 8) & 0x000000ff;
nuclear@14 83 buf[2] = (aValue >> 16) & 0x000000ff;
nuclear@14 84 buf[3] = (aValue >> 24) & 0x000000ff;
nuclear@14 85 _ctmStreamWrite(self, (void *) buf, 4);
nuclear@14 86 }
nuclear@14 87
nuclear@14 88 //-----------------------------------------------------------------------------
nuclear@14 89 // _ctmStreamReadFLOAT() - Read a floating point value from a stream in a
nuclear@14 90 // machine endian independent manner (for portability).
nuclear@14 91 //-----------------------------------------------------------------------------
nuclear@14 92 CTMfloat _ctmStreamReadFLOAT(_CTMcontext * self)
nuclear@14 93 {
nuclear@14 94 union {
nuclear@14 95 CTMfloat f;
nuclear@14 96 CTMuint i;
nuclear@14 97 } u;
nuclear@14 98 u.i = _ctmStreamReadUINT(self);
nuclear@14 99 return u.f;
nuclear@14 100 }
nuclear@14 101
nuclear@14 102 //-----------------------------------------------------------------------------
nuclear@14 103 // _ctmStreamWriteFLOAT() - Write a floating point value to a stream in a
nuclear@14 104 // machine endian independent manner (for portability).
nuclear@14 105 //-----------------------------------------------------------------------------
nuclear@14 106 void _ctmStreamWriteFLOAT(_CTMcontext * self, CTMfloat aValue)
nuclear@14 107 {
nuclear@14 108 union {
nuclear@14 109 CTMfloat f;
nuclear@14 110 CTMuint i;
nuclear@14 111 } u;
nuclear@14 112 u.f = aValue;
nuclear@14 113 _ctmStreamWriteUINT(self, u.i);
nuclear@14 114 }
nuclear@14 115
nuclear@14 116 //-----------------------------------------------------------------------------
nuclear@14 117 // _ctmStreamReadSTRING() - Read a string value from a stream. The format of
nuclear@14 118 // the string in the stream is: an unsigned integer (string length) followed by
nuclear@14 119 // the string (without null termination).
nuclear@14 120 //-----------------------------------------------------------------------------
nuclear@14 121 void _ctmStreamReadSTRING(_CTMcontext * self, char ** aValue)
nuclear@14 122 {
nuclear@14 123 CTMuint len;
nuclear@14 124
nuclear@14 125 // Clear the old string
nuclear@14 126 if(*aValue)
nuclear@14 127 {
nuclear@14 128 free(*aValue);
nuclear@14 129 *aValue = (char *) 0;
nuclear@14 130 }
nuclear@14 131
nuclear@14 132 // Get string length
nuclear@14 133 len = _ctmStreamReadUINT(self);
nuclear@14 134
nuclear@14 135 // Read string
nuclear@14 136 if(len > 0)
nuclear@14 137 {
nuclear@14 138 *aValue = (char *) malloc(len + 1);
nuclear@14 139 if(*aValue)
nuclear@14 140 {
nuclear@14 141 _ctmStreamRead(self, (void *) *aValue, len);
nuclear@14 142 (*aValue)[len] = 0;
nuclear@14 143 }
nuclear@14 144 }
nuclear@14 145 }
nuclear@14 146
nuclear@14 147 //-----------------------------------------------------------------------------
nuclear@14 148 // _ctmStreamWriteSTRING() - Write a string value to a stream. The format of
nuclear@14 149 // the string in the stream is: an unsigned integer (string length) followed by
nuclear@14 150 // the string (without null termination).
nuclear@14 151 //-----------------------------------------------------------------------------
nuclear@14 152 void _ctmStreamWriteSTRING(_CTMcontext * self, const char * aValue)
nuclear@14 153 {
nuclear@14 154 CTMuint len;
nuclear@14 155
nuclear@14 156 // Get string length
nuclear@14 157 if(aValue)
nuclear@14 158 len = strlen(aValue);
nuclear@14 159 else
nuclear@14 160 len = 0;
nuclear@14 161
nuclear@14 162 // Write string length
nuclear@14 163 _ctmStreamWriteUINT(self, len);
nuclear@14 164
nuclear@14 165 // Write string
nuclear@14 166 if(len > 0)
nuclear@14 167 _ctmStreamWrite(self, (void *) aValue, len);
nuclear@14 168 }
nuclear@14 169
nuclear@14 170 //-----------------------------------------------------------------------------
nuclear@14 171 // _ctmStreamReadPackedInts() - Read an compressed binary integer data array
nuclear@14 172 // from a stream, and uncompress it.
nuclear@14 173 //-----------------------------------------------------------------------------
nuclear@14 174 int _ctmStreamReadPackedInts(_CTMcontext * self, CTMint * aData,
nuclear@14 175 CTMuint aCount, CTMuint aSize, CTMint aSignedInts)
nuclear@14 176 {
nuclear@14 177 size_t packedSize, unpackedSize;
nuclear@14 178 CTMuint i, k, x;
nuclear@14 179 CTMint value;
nuclear@14 180 unsigned char * packed, * tmp;
nuclear@14 181 unsigned char props[5];
nuclear@14 182 int lzmaRes;
nuclear@14 183
nuclear@14 184 // Read packed data size from the stream
nuclear@14 185 packedSize = (size_t) _ctmStreamReadUINT(self);
nuclear@14 186
nuclear@14 187 // Read LZMA compression props from the stream
nuclear@14 188 _ctmStreamRead(self, (void *) props, 5);
nuclear@14 189
nuclear@14 190 // Allocate memory and read the packed data from the stream
nuclear@14 191 packed = (unsigned char *) malloc(packedSize);
nuclear@14 192 if(!packed)
nuclear@14 193 {
nuclear@14 194 self->mError = CTM_OUT_OF_MEMORY;
nuclear@14 195 return CTM_FALSE;
nuclear@14 196 }
nuclear@14 197 _ctmStreamRead(self, (void *) packed, packedSize);
nuclear@14 198
nuclear@14 199 // Allocate memory for interleaved array
nuclear@14 200 tmp = (unsigned char *) malloc(aCount * aSize * 4);
nuclear@14 201 if(!tmp)
nuclear@14 202 {
nuclear@14 203 free(packed);
nuclear@14 204 self->mError = CTM_OUT_OF_MEMORY;
nuclear@14 205 return CTM_FALSE;
nuclear@14 206 }
nuclear@14 207
nuclear@14 208 // Uncompress
nuclear@14 209 unpackedSize = aCount * aSize * 4;
nuclear@14 210 lzmaRes = LzmaUncompress(tmp, &unpackedSize, packed,
nuclear@14 211 &packedSize, props, 5);
nuclear@14 212
nuclear@14 213 // Free the packed array
nuclear@14 214 free(packed);
nuclear@14 215
nuclear@14 216 // Error?
nuclear@14 217 if((lzmaRes != SZ_OK) || (unpackedSize != aCount * aSize * 4))
nuclear@14 218 {
nuclear@14 219 self->mError = CTM_LZMA_ERROR;
nuclear@14 220 free(tmp);
nuclear@14 221 return CTM_FALSE;
nuclear@14 222 }
nuclear@14 223
nuclear@14 224 // Convert interleaved array to integers
nuclear@14 225 for(i = 0; i < aCount; ++ i)
nuclear@14 226 {
nuclear@14 227 for(k = 0; k < aSize; ++ k)
nuclear@14 228 {
nuclear@14 229 value = (CTMint) tmp[i + k * aCount + 3 * aCount * aSize] |
nuclear@14 230 (((CTMint) tmp[i + k * aCount + 2 * aCount * aSize]) << 8) |
nuclear@14 231 (((CTMint) tmp[i + k * aCount + aCount * aSize]) << 16) |
nuclear@14 232 (((CTMint) tmp[i + k * aCount]) << 24);
nuclear@14 233 // Convert signed magnitude to two's complement?
nuclear@14 234 if(aSignedInts)
nuclear@14 235 {
nuclear@14 236 x = (CTMuint) value;
nuclear@14 237 value = (x & 1) ? -(CTMint)((x + 1) >> 1) : (CTMint)(x >> 1);
nuclear@14 238 }
nuclear@14 239 aData[i * aSize + k] = value;
nuclear@14 240 }
nuclear@14 241 }
nuclear@14 242
nuclear@14 243 // Free the interleaved array
nuclear@14 244 free(tmp);
nuclear@14 245
nuclear@14 246 return CTM_TRUE;
nuclear@14 247 }
nuclear@14 248
nuclear@14 249 //-----------------------------------------------------------------------------
nuclear@14 250 // _ctmStreamWritePackedInts() - Compress a binary integer data array, and
nuclear@14 251 // write it to a stream.
nuclear@14 252 //-----------------------------------------------------------------------------
nuclear@14 253 int _ctmStreamWritePackedInts(_CTMcontext * self, CTMint * aData,
nuclear@14 254 CTMuint aCount, CTMuint aSize, CTMint aSignedInts)
nuclear@14 255 {
nuclear@14 256 int lzmaRes, lzmaAlgo;
nuclear@14 257 CTMuint i, k;
nuclear@14 258 CTMint value;
nuclear@14 259 size_t bufSize, outPropsSize;
nuclear@14 260 unsigned char * packed, outProps[5], *tmp;
nuclear@14 261 #ifdef __DEBUG_
nuclear@14 262 CTMuint negCount = 0;
nuclear@14 263 #endif
nuclear@14 264
nuclear@14 265 // Allocate memory for interleaved array
nuclear@14 266 tmp = (unsigned char *) malloc(aCount * aSize * 4);
nuclear@14 267 if(!tmp)
nuclear@14 268 {
nuclear@14 269 self->mError = CTM_OUT_OF_MEMORY;
nuclear@14 270 return CTM_FALSE;
nuclear@14 271 }
nuclear@14 272
nuclear@14 273 // Convert integers to an interleaved array
nuclear@14 274 for(i = 0; i < aCount; ++ i)
nuclear@14 275 {
nuclear@14 276 for(k = 0; k < aSize; ++ k)
nuclear@14 277 {
nuclear@14 278 value = aData[i * aSize + k];
nuclear@14 279 // Convert two's complement to signed magnitude?
nuclear@14 280 if(aSignedInts)
nuclear@14 281 value = value < 0 ? -1 - (value << 1) : value << 1;
nuclear@14 282 #ifdef __DEBUG_
nuclear@14 283 else if(value < 0)
nuclear@14 284 ++ negCount;
nuclear@14 285 #endif
nuclear@14 286 tmp[i + k * aCount + 3 * aCount * aSize] = value & 0x000000ff;
nuclear@14 287 tmp[i + k * aCount + 2 * aCount * aSize] = (value >> 8) & 0x000000ff;
nuclear@14 288 tmp[i + k * aCount + aCount * aSize] = (value >> 16) & 0x000000ff;
nuclear@14 289 tmp[i + k * aCount] = (value >> 24) & 0x000000ff;
nuclear@14 290 }
nuclear@14 291 }
nuclear@14 292
nuclear@14 293 // Allocate memory for the packed data
nuclear@14 294 bufSize = 1000 + aCount * aSize * 4;
nuclear@14 295 packed = (unsigned char *) malloc(bufSize);
nuclear@14 296 if(!packed)
nuclear@14 297 {
nuclear@14 298 free(tmp);
nuclear@14 299 self->mError = CTM_OUT_OF_MEMORY;
nuclear@14 300 return CTM_FALSE;
nuclear@14 301 }
nuclear@14 302
nuclear@14 303 // Call LZMA to compress
nuclear@14 304 outPropsSize = 5;
nuclear@14 305 lzmaAlgo = (self->mCompressionLevel < 1 ? 0 : 1);
nuclear@14 306 lzmaRes = LzmaCompress(packed,
nuclear@14 307 &bufSize,
nuclear@14 308 (const unsigned char *) tmp,
nuclear@14 309 aCount * aSize * 4,
nuclear@14 310 outProps,
nuclear@14 311 &outPropsSize,
nuclear@14 312 self->mCompressionLevel, // Level (0-9)
nuclear@14 313 0, -1, -1, -1, -1, -1, // Default values (set by level)
nuclear@14 314 lzmaAlgo // Algorithm (0 = fast, 1 = normal)
nuclear@14 315 );
nuclear@14 316
nuclear@14 317 // Free temporary array
nuclear@14 318 free(tmp);
nuclear@14 319
nuclear@14 320 // Error?
nuclear@14 321 if(lzmaRes != SZ_OK)
nuclear@14 322 {
nuclear@14 323 self->mError = CTM_LZMA_ERROR;
nuclear@14 324 free(packed);
nuclear@14 325 return CTM_FALSE;
nuclear@14 326 }
nuclear@14 327
nuclear@14 328 #ifdef __DEBUG_
nuclear@14 329 printf("%d->%d bytes (%d negative words)\n", aCount * aSize * 4, (int) bufSize, negCount);
nuclear@14 330 #endif
nuclear@14 331
nuclear@14 332 // Write packed data size to the stream
nuclear@14 333 _ctmStreamWriteUINT(self, (CTMuint) bufSize);
nuclear@14 334
nuclear@14 335 // Write LZMA compression props to the stream
nuclear@14 336 _ctmStreamWrite(self, (void *) outProps, 5);
nuclear@14 337
nuclear@14 338 // Write the packed data to the stream
nuclear@14 339 _ctmStreamWrite(self, (void *) packed, (CTMuint) bufSize);
nuclear@14 340
nuclear@14 341 // Free the packed data
nuclear@14 342 free(packed);
nuclear@14 343
nuclear@14 344 return CTM_TRUE;
nuclear@14 345 }
nuclear@14 346
nuclear@14 347 //-----------------------------------------------------------------------------
nuclear@14 348 // _ctmStreamReadPackedFloats() - Read an compressed binary float data array
nuclear@14 349 // from a stream, and uncompress it.
nuclear@14 350 //-----------------------------------------------------------------------------
nuclear@14 351 int _ctmStreamReadPackedFloats(_CTMcontext * self, CTMfloat * aData,
nuclear@14 352 CTMuint aCount, CTMuint aSize)
nuclear@14 353 {
nuclear@14 354 CTMuint i, k;
nuclear@14 355 size_t packedSize, unpackedSize;
nuclear@14 356 union {
nuclear@14 357 CTMfloat f;
nuclear@14 358 CTMint i;
nuclear@14 359 } value;
nuclear@14 360 unsigned char * packed, * tmp;
nuclear@14 361 unsigned char props[5];
nuclear@14 362 int lzmaRes;
nuclear@14 363
nuclear@14 364 // Read packed data size from the stream
nuclear@14 365 packedSize = (size_t) _ctmStreamReadUINT(self);
nuclear@14 366
nuclear@14 367 // Read LZMA compression props from the stream
nuclear@14 368 _ctmStreamRead(self, (void *) props, 5);
nuclear@14 369
nuclear@14 370 // Allocate memory and read the packed data from the stream
nuclear@14 371 packed = (unsigned char *) malloc(packedSize);
nuclear@14 372 if(!packed)
nuclear@14 373 {
nuclear@14 374 self->mError = CTM_OUT_OF_MEMORY;
nuclear@14 375 return CTM_FALSE;
nuclear@14 376 }
nuclear@14 377 _ctmStreamRead(self, (void *) packed, packedSize);
nuclear@14 378
nuclear@14 379 // Allocate memory for interleaved array
nuclear@14 380 tmp = (unsigned char *) malloc(aCount * aSize * 4);
nuclear@14 381 if(!tmp)
nuclear@14 382 {
nuclear@14 383 free(packed);
nuclear@14 384 self->mError = CTM_OUT_OF_MEMORY;
nuclear@14 385 return CTM_FALSE;
nuclear@14 386 }
nuclear@14 387
nuclear@14 388 // Uncompress
nuclear@14 389 unpackedSize = aCount * aSize * 4;
nuclear@14 390 lzmaRes = LzmaUncompress(tmp, &unpackedSize, packed,
nuclear@14 391 &packedSize, props, 5);
nuclear@14 392
nuclear@14 393 // Free the packed array
nuclear@14 394 free(packed);
nuclear@14 395
nuclear@14 396 // Error?
nuclear@14 397 if((lzmaRes != SZ_OK) || (unpackedSize != aCount * aSize * 4))
nuclear@14 398 {
nuclear@14 399 self->mError = CTM_LZMA_ERROR;
nuclear@14 400 free(tmp);
nuclear@14 401 return CTM_FALSE;
nuclear@14 402 }
nuclear@14 403
nuclear@14 404 // Convert interleaved array to floats
nuclear@14 405 for(i = 0; i < aCount; ++ i)
nuclear@14 406 {
nuclear@14 407 for(k = 0; k < aSize; ++ k)
nuclear@14 408 {
nuclear@14 409 value.i = (CTMint) tmp[i + k * aCount + 3 * aCount * aSize] |
nuclear@14 410 (((CTMint) tmp[i + k * aCount + 2 * aCount * aSize]) << 8) |
nuclear@14 411 (((CTMint) tmp[i + k * aCount + aCount * aSize]) << 16) |
nuclear@14 412 (((CTMint) tmp[i + k * aCount]) << 24);
nuclear@14 413 aData[i * aSize + k] = value.f;
nuclear@14 414 }
nuclear@14 415 }
nuclear@14 416
nuclear@14 417 // Free the interleaved array
nuclear@14 418 free(tmp);
nuclear@14 419
nuclear@14 420 return CTM_TRUE;
nuclear@14 421 }
nuclear@14 422
nuclear@14 423 //-----------------------------------------------------------------------------
nuclear@14 424 // _ctmStreamWritePackedFloats() - Compress a binary float data array, and
nuclear@14 425 // write it to a stream.
nuclear@14 426 //-----------------------------------------------------------------------------
nuclear@14 427 int _ctmStreamWritePackedFloats(_CTMcontext * self, CTMfloat * aData,
nuclear@14 428 CTMuint aCount, CTMuint aSize)
nuclear@14 429 {
nuclear@14 430 int lzmaRes, lzmaAlgo;
nuclear@14 431 CTMuint i, k;
nuclear@14 432 union {
nuclear@14 433 CTMfloat f;
nuclear@14 434 CTMint i;
nuclear@14 435 } value;
nuclear@14 436 size_t bufSize, outPropsSize;
nuclear@14 437 unsigned char * packed, outProps[5], *tmp;
nuclear@14 438
nuclear@14 439 // Allocate memory for interleaved array
nuclear@14 440 tmp = (unsigned char *) malloc(aCount * aSize * 4);
nuclear@14 441 if(!tmp)
nuclear@14 442 {
nuclear@14 443 self->mError = CTM_OUT_OF_MEMORY;
nuclear@14 444 return CTM_FALSE;
nuclear@14 445 }
nuclear@14 446
nuclear@14 447 // Convert floats to an interleaved array
nuclear@14 448 for(i = 0; i < aCount; ++ i)
nuclear@14 449 {
nuclear@14 450 for(k = 0; k < aSize; ++ k)
nuclear@14 451 {
nuclear@14 452 value.f = aData[i * aSize + k];
nuclear@14 453 tmp[i + k * aCount + 3 * aCount * aSize] = value.i & 0x000000ff;
nuclear@14 454 tmp[i + k * aCount + 2 * aCount * aSize] = (value.i >> 8) & 0x000000ff;
nuclear@14 455 tmp[i + k * aCount + aCount * aSize] = (value.i >> 16) & 0x000000ff;
nuclear@14 456 tmp[i + k * aCount] = (value.i >> 24) & 0x000000ff;
nuclear@14 457 }
nuclear@14 458 }
nuclear@14 459
nuclear@14 460 // Allocate memory for the packed data
nuclear@14 461 bufSize = 1000 + aCount * aSize * 4;
nuclear@14 462 packed = (unsigned char *) malloc(bufSize);
nuclear@14 463 if(!packed)
nuclear@14 464 {
nuclear@14 465 free(tmp);
nuclear@14 466 self->mError = CTM_OUT_OF_MEMORY;
nuclear@14 467 return CTM_FALSE;
nuclear@14 468 }
nuclear@14 469
nuclear@14 470 // Call LZMA to compress
nuclear@14 471 outPropsSize = 5;
nuclear@14 472 lzmaAlgo = (self->mCompressionLevel < 1 ? 0 : 1);
nuclear@14 473 lzmaRes = LzmaCompress(packed,
nuclear@14 474 &bufSize,
nuclear@14 475 (const unsigned char *) tmp,
nuclear@14 476 aCount * aSize * 4,
nuclear@14 477 outProps,
nuclear@14 478 &outPropsSize,
nuclear@14 479 self->mCompressionLevel, // Level (0-9)
nuclear@14 480 0, -1, -1, -1, -1, -1, // Default values (set by level)
nuclear@14 481 lzmaAlgo // Algorithm (0 = fast, 1 = normal)
nuclear@14 482 );
nuclear@14 483
nuclear@14 484 // Free temporary array
nuclear@14 485 free(tmp);
nuclear@14 486
nuclear@14 487 // Error?
nuclear@14 488 if(lzmaRes != SZ_OK)
nuclear@14 489 {
nuclear@14 490 self->mError = CTM_LZMA_ERROR;
nuclear@14 491 free(packed);
nuclear@14 492 return CTM_FALSE;
nuclear@14 493 }
nuclear@14 494
nuclear@14 495 #ifdef __DEBUG_
nuclear@14 496 printf("%d->%d bytes\n", aCount * aSize * 4, (int) bufSize);
nuclear@14 497 #endif
nuclear@14 498
nuclear@14 499 // Write packed data size to the stream
nuclear@14 500 _ctmStreamWriteUINT(self, (CTMuint) bufSize);
nuclear@14 501
nuclear@14 502 // Write LZMA compression props to the stream
nuclear@14 503 _ctmStreamWrite(self, (void *) outProps, 5);
nuclear@14 504
nuclear@14 505 // Write the packed data to the stream
nuclear@14 506 _ctmStreamWrite(self, (void *) packed, (CTMuint) bufSize);
nuclear@14 507
nuclear@14 508 // Free the packed data
nuclear@14 509 free(packed);
nuclear@14 510
nuclear@14 511 return CTM_TRUE;
nuclear@14 512 }