Develop and Download Open Source Software

Browse Subversion Repository

Contents of /misc.h

Parent Directory Parent Directory | Revision Log Revision Log


Revision 18 - (show annotations) (download) (as text)
Mon Oct 11 13:26:23 2010 UTC (13 years, 6 months ago) by berupon
File MIME type: text/x-chdr
File size: 25207 byte(s)
GUIで、圧縮設定を調整して結果を確認出来るアプリケーションの作成開始。
1
2 #include "RanCode.h"
3 //#include "RanCodeAdp.h"
4
5 template <typename T, typename T2>
6 void gather(
7 const T* in, int lineOffsetBytes,
8 T2 values[8][8]
9 )
10 {
11 const T* src = in;
12 for (size_t i=0; i<8; ++i) {
13 for (size_t j=0; j<8; ++j) {
14 values[i][j] = src[j];
15 }
16 OffsetPtr(src, lineOffsetBytes);
17 }
18 }
19
20 template <typename T, typename T2>
21 void scatter(
22 T* out, int lineOffsetBytes,
23 T2 values[8][8]
24 )
25 {
26 T* dest = out;
27 for (size_t i=0; i<8; ++i) {
28 for (size_t j=0; j<8; ++j) {
29 dest[j] = values[i][j];
30 }
31 OffsetPtr(dest, lineOffsetBytes);
32 }
33 }
34
35 int paethPredictor(int left, int above, int upperLeft)
36 {
37 int initial = left + (above - upperLeft);
38 int diffLeft = std::abs(initial - left);
39 int diffAbove = std::abs(initial - above);
40 int diffUpperLeft = std::abs(initial - upperLeft);
41 if (diffLeft <= diffAbove && diffLeft <= diffUpperLeft) {
42 return left;
43 }else if (diffAbove <= diffUpperLeft) {
44 return above;
45 }else {
46 return upperLeft;
47 }
48 }
49
50 int LOCO_IPredictor(int left, int above, int upperLeft)
51 {
52 int minLeftAbove = std::min<int>(left, above);
53 int maxLeftAbove = std::max<int>(left, above);
54 if (upperLeft > maxLeftAbove) {
55 return minLeftAbove;
56 }else if (upperLeft < minLeftAbove) {
57 return maxLeftAbove;
58 }else {
59 return left + above - upperLeft;
60 }
61 }
62
63 class BitWriter
64 {
65 public:
66 BitWriter(unsigned char* dest)
67 :
68 nBits_(0),
69 dest_(dest),
70 initialDest_(dest),
71 counter_(0)
72 {
73 *dest_ = 0;
74 }
75 void putBit(bool b)
76 {
77 int v = b ? 1 : 0;
78 (*dest_) |= (v << (7 - counter_));
79 ++counter_;
80 if (counter_ == 8) {
81 ++dest_;
82 *dest_ = 0;
83 counter_ = 0;
84 }
85 ++nBits_;
86 }
87 size_t nBits() const { return nBits_; }
88 size_t nBytes() const { return (dest_ - initialDest_) + (counter_ ? 1 : 0); }
89 private:
90 size_t nBits_;
91 unsigned char counter_;
92 unsigned char* dest_;
93 unsigned char* initialDest_;
94 };
95
96 class BitReader
97 {
98 public:
99 BitReader(const unsigned char* src)
100 :
101 src_(src),
102 initialSrc_(src),
103 counter_(0)
104 {
105 }
106
107 bool getBit()
108 {
109 bool ret = *src_ & (1 << (7-counter_));
110 ++counter_;
111 if (counter_ == 8) {
112 counter_ = 0;
113 ++src_;
114 }
115 return ret;
116 }
117
118 size_t nBytes() const { return (src_ - initialSrc_) + (counter_ ? 1 : 0); }
119
120 private:
121 unsigned char counter_;
122 const unsigned char* src_;
123 const unsigned char* initialSrc_;
124 };
125
126 class RiceCoder
127 {
128 public:
129 RiceCoder(size_t shift)
130 :
131 shift_(shift)
132 {
133 }
134
135 void Encode(size_t value, BitWriter& writer)
136 {
137 size_t p = value >> shift_;
138 for (size_t i=0; i<p; ++i) {
139 writer.putBit(false);
140 }
141 writer.putBit(true);
142 int v = 1;
143 for (size_t i=0; i<shift_; ++i) {
144 writer.putBit(value & v);
145 v <<= 1;
146 }
147 }
148
149 size_t Decode(BitReader& reader)
150 {
151 size_t q = 0;
152 while (!reader.getBit()) ++q;
153 size_t ret = q << shift_;
154 for (size_t i=0; i<shift_; ++i) {
155 if (reader.getBit()) {
156 ret += 1 << i;
157 }
158 }
159 return ret;
160 }
161
162 private:
163 size_t shift_;
164 };
165
166 void findZeroOneInfos(
167 size_t hBlockCount,
168 size_t vBlockCount,
169 const int* src,
170 int* dst,
171 int* dst2,
172 size_t limit
173 )
174 {
175 const int totalBlockCount = static_cast<int>(hBlockCount * vBlockCount);
176 const int* from = src;
177
178 // pass DC0
179 from += totalBlockCount;
180
181 std::fill(dst, dst+totalBlockCount, 1);
182 std::fill(dst2, dst2+totalBlockCount*8, 0);
183
184 for (size_t i=1; i<8; ++i) {
185 unsigned char blockSize = 1 + i*2;
186 if (i<limit) {
187 from += blockSize * totalBlockCount;
188 continue;
189 }
190 int* arr = dst2 + totalBlockCount * i;
191 for (size_t j=0; j<totalBlockCount; ++j) {
192 for (size_t k=0; k<blockSize; ++k) {
193 int v = abs(from[k]);
194 if (v > 1) {
195 dst[j] = 0;
196 arr[j] = -1;
197 break;
198 }
199 }
200 from += blockSize;
201 }
202 int hoge = 0;
203 }
204
205 for (size_t i=0; i<totalBlockCount; ++i) {
206 int sum = 0;
207 for (size_t j=1; j<8; ++j) {
208 sum |= std::abs(dst2[j*totalBlockCount + i]) << (j-limit);
209 }
210 dst2[i] = sum;
211 }
212 int hoge = 0;
213 }
214
215 struct CompressInfo
216 {
217 int mini;
218 int maxi;
219 size_t max;
220 int hists[1024];
221 int phists[1024];
222 int mhists[1024];
223 int zeroRepeatHist[1024*128];
224
225 size_t zeroOneOnlyAreaHist[2];
226 size_t nonZeroOneOnlyAreaHist[1024];
227
228
229 size_t srcCount;
230 size_t signFlagsCount;
231 size_t initialCompressedLen;
232 size_t totalLen;
233 };
234
235 static const size_t DC_BLOCKCOUNT_BORDER = 8192;
236
237 #define COMBINE_ZERO_FLAGS 0 // ���������������01���������������������������������������������������������������������������������������
238
239 #if COMBINE_ZERO_FLAGS
240 std::vector<size_t> zeroFlagCompressedSizes;
241 std::vector<int> zeroFlagValues;
242 #endif
243
244 size_t compressSub(
245 int* src,
246 const int* pZeroOneInfos,
247 size_t zeroOneFlag,
248 size_t blockCount, size_t blockSize,
249 unsigned char* dest, size_t destLen,
250 unsigned char* tmp,
251 unsigned char* tmp2,
252 unsigned char* tmp3,
253 CompressInfo& cinfo
254 )
255 {
256 unsigned char* initialDest = dest;
257 size_t srcCount = blockCount * blockSize;
258
259 assert(destLen > 4);
260
261 int mini = cinfo.mini;
262 int maxi = cinfo.maxi;
263 size_t max = std::max<int>(maxi, std::abs(mini));
264
265 int* hists = cinfo.hists;
266 int* phists = cinfo.phists;
267 int* mhists = cinfo.mhists;
268
269 int initialCompressedLen = 0;
270
271 // DC���������������������������������������RangeCoder������������Golomb-Rice���������������
272 //���������������������������������RangeCoder������������������������������������������������������������������������������������������������������
273 if (blockSize == 1 && blockCount < DC_BLOCKCOUNT_BORDER) {
274 int b = 0;
275
276 if (max > 2048) {
277 b = 7;
278 }else if (max > 1024) {
279 b = 6;
280 }else if (max > 512) {
281 b = 5;
282 }else if (max > 256) {
283 b = 4;
284 }else if (max > 128+64) {
285 b = 3;
286 }else if (max > 96) {
287 b = 2;
288 }else if (max > 32) {
289 b = 1;
290 }else {
291 b = 0;
292 }
293
294 BitWriter bitWriter(tmp);
295 RiceCoder riceCoder(b);
296 int* from = src;
297 for (size_t i=0; i<blockCount; ++i) {
298 for (size_t j=0; j<blockSize; ++j) {
299 riceCoder.Encode(*from++, bitWriter);
300 }
301 }
302 initialCompressedLen = bitWriter.nBytes();
303
304 *dest++ = 0;
305 *dest++ = b;
306 memcpy(dest+4, tmp, initialCompressedLen);
307 *((size_t*)dest) = initialCompressedLen;
308 dest += 4;
309 dest += initialCompressedLen;
310
311 }else {
312 initialCompressedLen = srcCount * 4;
313 Encode(src, srcCount, max, 0, tmp, initialCompressedLen);
314
315 int encodedValueSizes[2];
316 int* from = src;
317 if (pZeroOneInfos) {
318 std::vector<int> values;
319 for (size_t i=0; i<blockCount; ++i) {
320 // if (!(pZeroOneInfos[i] & zeroOneFlag)) {
321 if (pZeroOneInfos[i]) {
322 for (size_t j=0; j<blockSize; ++j) {
323 int val = src[i*blockSize+j];
324 assert(val < 2);
325 cinfo.zeroOneOnlyAreaHist[val]++;
326 values.push_back(val);
327 }
328 }
329 }
330 encodedValueSizes[0] = blockCount*blockSize;
331 Encode(&values[0], values.size(), 1, 0, tmp2, encodedValueSizes[0]);
332 #if COMBINE_ZERO_FLAGS
333 zeroFlagValues.insert(zeroFlagValues.end(), values.begin(), values.end());
334 zeroFlagCompressedSizes.push_back(encodedValueSizes[0]);
335 #endif
336 values.clear();
337 int maxV = 0;
338 for (size_t i=0; i<blockCount; ++i) {
339 // if ((pZeroOneInfos[i] & zeroOneFlag)) {
340 if (!pZeroOneInfos[i]) {
341 for (size_t j=0; j<blockSize; ++j) {
342 int val = src[i*blockSize+j];
343 maxV = std::max<int>(maxV, val);
344 cinfo.nonZeroOneOnlyAreaHist[val]++;
345 values.push_back(val);
346 }
347 }
348 }
349 encodedValueSizes[1] = blockCount*blockSize;
350 Encode(&values[0], values.size(), maxV, 0, tmp3, encodedValueSizes[1]);
351 /*
352 {
353 int zeroRepeat = 0;
354 int zeroRepeatHist[1024] = {0};
355 int repeatMax = 0;
356 int val = 0;
357 int valMax = 0;
358 std::vector<int> zeroRepeatRecs;
359 std::vector<int> nonZeroRecs;
360 for (size_t i=0; i<values.size(); ++i) {
361 val = values[i];
362 if (val == 0) {
363 ++zeroRepeat;
364 }else {
365 zeroRepeatRecs.push_back(zeroRepeat);
366 ++zeroRepeatHist[zeroRepeat];
367 repeatMax = std::max(repeatMax, zeroRepeat);
368 zeroRepeat = 0;
369 nonZeroRecs.push_back(val);
370 valMax = std::max(valMax, val);
371 }
372 }
373 if (zeroRepeat) {
374 zeroRepeatRecs.push_back(zeroRepeat);
375 ++zeroRepeatHist[zeroRepeat];
376 repeatMax = std::max(repeatMax, zeroRepeat);
377 zeroRepeat = 0;
378 nonZeroRecs.push_back(val);
379 valMax = std::max(valMax, val);
380 }
381 std::vector<int> newRecs;
382 int nonZeroRefPos = 0;
383 for (size_t i=0; i<zeroRepeatRecs.size(); ++i) {
384 int v = zeroRepeatRecs[i];
385 if (v) {
386 newRecs.push_back(v);
387 }
388 newRecs.push_back(repeatMax + nonZeroRecs[nonZeroRefPos++]);
389 }
390 int encodedSize1 = blockCount*blockSize;
391 int encodedSize2 = blockCount*blockSize;
392 std::vector<unsigned char> recbuff(encodedSize1);
393 Encode(&zeroRepeatRecs[0], zeroRepeatRecs.size(), repeatMax, 0, &recbuff[0], encodedSize1);
394 Encode(&nonZeroRecs[0], nonZeroRecs.size(), maxV, 1, &recbuff[0], encodedSize2);
395 int hoget = 0;
396 }
397 */
398
399 int totalSize = encodedValueSizes[0] + encodedValueSizes[1];
400 size_t len = 0;
401 if (totalSize <= initialCompressedLen) {
402 *dest++ = 3;
403
404 for (size_t i=0; i<2; ++i) {
405 *((size_t*)dest) = encodedValueSizes[i];
406 dest += 4;
407 memcpy(dest, ((i==0)?tmp2:tmp3), encodedValueSizes[i]);
408 dest += encodedValueSizes[i];
409 }
410
411 goto label_end;
412 }
413
414 }
415
416 *dest++ = 1;
417 memcpy(dest+4, tmp, initialCompressedLen);
418 *((size_t*)dest) = initialCompressedLen;
419 dest += 4;
420 dest += initialCompressedLen;
421
422 }
423
424 label_end:
425 size_t destDiff = dest - initialDest;
426
427 cinfo.srcCount = srcCount;
428 cinfo.mini = mini;
429 cinfo.maxi = maxi;
430 cinfo.max = max;
431 cinfo.initialCompressedLen = initialCompressedLen;
432 cinfo.totalLen = destDiff;
433
434 return destDiff;
435 }
436
437 void predictEncode(
438 size_t hBlockCount,
439 size_t vBlockCount,
440 int* src,
441 int* tmp
442 )
443 {
444 const int totalBlockCount = static_cast<int>(hBlockCount * vBlockCount);
445
446 int* from = src;
447 int* to = tmp;
448 std::copy(from, from+totalBlockCount, to);
449 // first row
450 int left = *to;
451 int above = 0;
452 int upperLeft = 0;
453 int cur = 0;
454 ++to;
455 for (size_t i=1; i<hBlockCount; ++i) {
456 cur = *to;
457 *to = cur - left;
458 ++to;
459 left = cur;
460 }
461 int fromLineOffset = 0;
462 for (size_t y=1; y<vBlockCount; ++y) {
463 cur = *to;
464 above = from[fromLineOffset];
465 *to = cur - above;
466 left = cur;
467 upperLeft = above;
468 ++to;
469 int fromPos = fromLineOffset + 1;
470 for (size_t x=1; x<hBlockCount; ++x) {
471 above = from[fromPos];
472 cur = *to;
473 *to = cur - LOCO_IPredictor(left, above, upperLeft);
474 ++to;
475 left = cur;
476 upperLeft = above;
477 ++fromPos;
478 }
479 fromLineOffset += hBlockCount;
480 }
481 std::copy(tmp, tmp+totalBlockCount, src);
482 }
483
484 void predictDecode(
485 size_t hBlockCount,
486 size_t vBlockCount,
487 int* src,
488 int* tmp
489 )
490 {
491 const int totalBlockCount = static_cast<int>(hBlockCount * vBlockCount);
492
493 int* to = tmp;
494 std::copy(src,src+totalBlockCount, to);
495
496 // paeth predictor to DC0
497 // first row
498 int left = *to;
499 int above = 0;
500 int upperLeft = 0;
501 int cur = 0;
502
503 int writePos;
504 writePos = 1;
505 for (size_t i=1; i<hBlockCount; ++i) {
506 cur = to[writePos] + left;
507 to[writePos] = cur;
508 left = cur;
509 ++writePos;
510 }
511 int toLineOffset = hBlockCount;
512 int diff = 0;
513 for (size_t y=1; y<vBlockCount; ++y) {
514 above = to[toLineOffset - hBlockCount];
515 diff = to[toLineOffset];
516 cur = diff + above;
517 to[toLineOffset] = cur;
518 writePos = toLineOffset + 1;
519 left = cur;
520 upperLeft = above;
521 for (size_t x=1; x<hBlockCount; ++x) {
522 above = to[writePos - hBlockCount];
523 diff = to[writePos];
524 cur = diff + LOCO_IPredictor(left, above, upperLeft);
525 to[writePos] = cur;
526 left = cur;
527 upperLeft = above;
528 ++writePos;
529 }
530 toLineOffset += hBlockCount;
531 }
532
533 std::copy(to, to+totalBlockCount, src);
534
535 }
536
537 size_t collectInfos(
538 int* src,
539 size_t blockCount,
540 unsigned char* signFlags,
541 CompressInfo compressInfos[8]
542 )
543 {
544 size_t count = 0;
545 int* from = src;
546 for (size_t i=0; i<8; ++i) {
547 size_t blockSize = 1 + i * 2;
548 CompressInfo& ci = compressInfos[i];
549 int oldCount = count;
550 int mini = boost::integer_traits<int>::const_max;
551 int maxi = boost::integer_traits<int>::const_min;
552
553 int* hists = ci.hists;
554 int* phists = ci.phists;
555 int* mhists = ci.mhists;
556 int zeroRepeat = 0;
557 int* zeroRepeatHist = ci.zeroRepeatHist;
558 size_t srcCount = blockCount * blockSize;
559 for (size_t j=0; j<srcCount; ++j) {
560 int val = from[j];
561 mini = std::min<int>(val, mini);
562 maxi = std::max<int>(val, maxi);
563 if (val == 0) {
564 ++zeroRepeat;
565 }else {
566 signFlags[count++] = (val > 0) ? 255 : 0;
567 ++zeroRepeatHist[zeroRepeat];
568 zeroRepeat = 0;
569 }
570 if (val >= 0) {
571 ++phists[val];
572 }else {
573 ++mhists[-val];
574 }
575 val = std::abs(val);
576 from[j] = val;
577
578 ++hists[val];
579 }
580 if (zeroRepeat) {
581 ++zeroRepeatHist[zeroRepeat];
582 zeroRepeat = 0;
583 }
584 ci.mini = mini;
585 ci.maxi = maxi;
586 ci.max = std::max<int>(maxi, std::abs(mini));
587 ci.signFlagsCount = count - oldCount;
588 from += srcCount;
589 }
590 return count;
591 }
592
593 size_t compress(
594 size_t hBlockCount,
595 size_t vBlockCount,
596 const int* pZeroOneInfos,
597 size_t zeroOneLimit,
598 CompressInfo compressInfos[8],
599 int* src,
600 unsigned char* tmp1,
601 unsigned char* tmp2,
602 unsigned char* tmp3,
603 unsigned char* dest, size_t destLen
604 )
605 {
606 const int totalBlockCount = static_cast<int>(hBlockCount * vBlockCount);
607
608 int* from = src;
609 size_t progress = 0;
610
611 for (size_t i=0; i<8; ++i) {
612 const int* p01 = (i < zeroOneLimit) ? 0 : pZeroOneInfos;
613 size_t blockSize = 1 + i * 2;
614 progress += compressSub(from, p01, 1<<(i-zeroOneLimit), totalBlockCount, blockSize, dest+progress, destLen-progress, tmp1, tmp2, tmp3, compressInfos[i]);
615 from += totalBlockCount * blockSize;
616 }
617
618 #if COMBINE_ZERO_FLAGS
619 std::vector<unsigned char> tmp(10000);
620 int compressedSize = tmp.size();
621 Encode(&zeroFlagValues[0], zeroFlagValues.size(), 1, 0, &tmp[0], compressedSize);
622 #endif
623
624 return progress;
625 }
626
627 size_t decompressSub(
628 const unsigned char* src,
629 const int* pZeroOneInfos,
630 unsigned char* tmp,
631 int* tmp2,
632 int* dest,
633 size_t totalBlockCount,
634 size_t blockSize)
635 {
636 size_t destLen = totalBlockCount * blockSize;
637
638 const unsigned char* initialSrc = src;
639
640 unsigned char compressFlag = *src++;
641
642 if (blockSize == 1 && totalBlockCount < DC_BLOCKCOUNT_BORDER) {
643 unsigned char b = *src++;
644
645 size_t len = *(size_t*)src;
646 src += 4;
647
648 RiceCoder riceCoder(b);
649 BitReader bitReader(src);
650 for (size_t i=0; i<destLen; ++i) {
651 dest[i] = riceCoder.Decode(bitReader);
652 }
653
654 assert(len == bitReader.nBytes());
655 src += len;
656
657 }else {
658 if (compressFlag != 3) {
659 size_t len = *(size_t*)src;
660 src += 4;
661
662 int len2 = 0;
663 switch (compressFlag) {
664 case 1:
665 len2 = destLen*4;
666 Decode((unsigned char*)src, len, (int*)dest, len2);
667 break;
668 default:
669 assert(false);
670 }
671 src += len;
672 }else {
673 size_t sizes[2] = {0};
674 int resultSize = destLen * 4;
675
676 sizes[0] = *(size_t*)src;
677 src += 4;
678 memcpy(tmp, src, sizes[0]);
679 src += sizes[0];
680 Decode(tmp, sizes[0], tmp2, resultSize);
681
682 size_t count = 0;
683 for (size_t i=0; i<totalBlockCount; ++i) {
684 if (pZeroOneInfos[i]) {
685 for (size_t j=0; j<blockSize; ++j) {
686 dest[i*blockSize+j] = tmp2[count++];
687 }
688 }
689 }
690
691 sizes[1] = *(size_t*)src;
692 src += 4;
693 memcpy(tmp, src, sizes[1]);
694 src += sizes[1];
695 Decode(tmp, sizes[1], tmp2, resultSize);
696
697 count = 0;
698 for (size_t i=0; i<totalBlockCount; ++i) {
699 if (!pZeroOneInfos[i]) {
700 for (size_t j=0; j<blockSize; ++j) {
701 dest[i*blockSize+j] = tmp2[count++];
702 }
703 }
704 }
705
706 }
707 }
708 return src - initialSrc;
709 }
710
711 void reorderByFrequency(
712 size_t hBlockCount,
713 size_t vBlockCount,
714 const int* src,
715 int* dst
716 )
717 {
718 const size_t fromWidth = hBlockCount * 8;
719 const size_t fromWidth8 = fromWidth * 8;
720
721 int readPos;
722 const int* from = src;
723 int* to = dst;
724
725 // DC0
726 readPos = 0;
727 for (size_t y=0; y<vBlockCount; ++y) {
728 int fromPos = readPos;
729 for (size_t x=0; x<hBlockCount; ++x) {
730 *to++ = from[fromPos];
731 fromPos += 8;
732 }
733 readPos += fromWidth8;
734 }
735
736 // AC1
737 readPos = 0;
738 for (size_t y=0; y<vBlockCount; ++y) {
739 int fromPos = readPos;
740 for (size_t x=0; x<hBlockCount; ++x) {
741 *to++ = from[fromPos+fromWidth*0+1];
742 *to++ = from[fromPos+fromWidth*1+0];
743 *to++ = from[fromPos+fromWidth*1+1];
744 fromPos += 8;
745 }
746 readPos += fromWidth8;
747 }
748
749 // AC2
750 readPos = 0;
751 for (size_t y=0; y<vBlockCount; ++y) {
752 int fromPos = readPos;
753 for (size_t x=0; x<hBlockCount; ++x) {
754 *to++ = from[fromPos+fromWidth*0+2];
755 *to++ = from[fromPos+fromWidth*1+2];
756 *to++ = from[fromPos+fromWidth*2+0];
757 *to++ = from[fromPos+fromWidth*2+1];
758 *to++ = from[fromPos+fromWidth*2+2];
759 fromPos += 8;
760 }
761 readPos += fromWidth8;
762 }
763
764 // AC3
765 readPos = 0;
766 for (size_t y=0; y<vBlockCount; ++y) {
767 int fromPos = readPos;
768 for (size_t x=0; x<hBlockCount; ++x) {
769 *to++ = from[fromPos+fromWidth*0+3];
770 *to++ = from[fromPos+fromWidth*1+3];
771 *to++ = from[fromPos+fromWidth*2+3];
772 *to++ = from[fromPos+fromWidth*3+0];
773 *to++ = from[fromPos+fromWidth*3+1];
774 *to++ = from[fromPos+fromWidth*3+2];
775 *to++ = from[fromPos+fromWidth*3+3];
776 fromPos += 8;
777 }
778 readPos += fromWidth8;
779 }
780
781 // AC4
782 readPos = 0;
783 for (size_t y=0; y<vBlockCount; ++y) {
784 int fromPos = readPos;
785 for (size_t x=0; x<hBlockCount; ++x) {
786 *to++ = from[fromPos+fromWidth*0+4];
787 *to++ = from[fromPos+fromWidth*1+4];
788 *to++ = from[fromPos+fromWidth*2+4];
789 *to++ = from[fromPos+fromWidth*3+4];
790 *to++ = from[fromPos+fromWidth*4+0];
791 *to++ = from[fromPos+fromWidth*4+1];
792 *to++ = from[fromPos+fromWidth*4+2];
793 *to++ = from[fromPos+fromWidth*4+3];
794 *to++ = from[fromPos+fromWidth*4+4];
795 fromPos += 8;
796 }
797 readPos += fromWidth8;
798 }
799
800
801 // AC5
802 readPos = 0;
803 for (size_t y=0; y<vBlockCount; ++y) {
804 int fromPos = readPos;
805 for (size_t x=0; x<hBlockCount; ++x) {
806 *to++ = from[fromPos+fromWidth*0+5];
807 *to++ = from[fromPos+fromWidth*1+5];
808 *to++ = from[fromPos+fromWidth*2+5];
809 *to++ = from[fromPos+fromWidth*3+5];
810 *to++ = from[fromPos+fromWidth*4+5];
811 *to++ = from[fromPos+fromWidth*5+0];
812 *to++ = from[fromPos+fromWidth*5+1];
813 *to++ = from[fromPos+fromWidth*5+2];
814 *to++ = from[fromPos+fromWidth*5+3];
815 *to++ = from[fromPos+fromWidth*5+4];
816 *to++ = from[fromPos+fromWidth*5+5];
817 fromPos += 8;
818 }
819 readPos += fromWidth8;
820 }
821
822 // AC6
823 readPos = 0;
824 for (size_t y=0; y<vBlockCount; ++y) {
825 int fromPos = readPos;
826 for (size_t x=0; x<hBlockCount; ++x) {
827 *to++ = from[fromPos+fromWidth*0+6];
828 *to++ = from[fromPos+fromWidth*1+6];
829 *to++ = from[fromPos+fromWidth*2+6];
830 *to++ = from[fromPos+fromWidth*3+6];
831 *to++ = from[fromPos+fromWidth*4+6];
832 *to++ = from[fromPos+fromWidth*5+6];
833 *to++ = from[fromPos+fromWidth*6+0];
834 *to++ = from[fromPos+fromWidth*6+1];
835 *to++ = from[fromPos+fromWidth*6+2];
836 *to++ = from[fromPos+fromWidth*6+3];
837 *to++ = from[fromPos+fromWidth*6+4];
838 *to++ = from[fromPos+fromWidth*6+5];
839 *to++ = from[fromPos+fromWidth*6+6];
840 fromPos += 8;
841 }
842 readPos += fromWidth8;
843 }
844
845 // AC7
846 readPos = 0;
847 for (size_t y=0; y<vBlockCount; ++y) {
848 int fromPos = readPos;
849 for (size_t x=0; x<hBlockCount; ++x) {
850 *to++ = from[fromPos+fromWidth*0+7];
851 *to++ = from[fromPos+fromWidth*1+7];
852 *to++ = from[fromPos+fromWidth*2+7];
853 *to++ = from[fromPos+fromWidth*3+7];
854 *to++ = from[fromPos+fromWidth*4+7];
855 *to++ = from[fromPos+fromWidth*5+7];
856 *to++ = from[fromPos+fromWidth*6+7];
857 *to++ = from[fromPos+fromWidth*7+0];
858 *to++ = from[fromPos+fromWidth*7+1];
859 *to++ = from[fromPos+fromWidth*7+2];
860 *to++ = from[fromPos+fromWidth*7+3];
861 *to++ = from[fromPos+fromWidth*7+4];
862 *to++ = from[fromPos+fromWidth*7+5];
863 *to++ = from[fromPos+fromWidth*7+6];
864 *to++ = from[fromPos+fromWidth*7+7];
865 fromPos += 8;
866 }
867 readPos += fromWidth8;
868 }
869
870 }
871
872 void reorderByPosition(
873 size_t hBlockCount,
874 size_t vBlockCount,
875 const int* src,
876 int* dest
877 )
878 {
879 const size_t toWidth = hBlockCount * 8;
880 const size_t toWidth8 = toWidth * 8;
881
882 const int* from = src;
883 int* to = dest;
884 int writePos = 0;
885
886 // DC0
887 writePos = 0;
888 for (size_t y=0; y<vBlockCount; ++y) {
889 int toPos = writePos;
890 for (size_t x=0; x<hBlockCount; ++x) {
891 to[toPos] = *from++;
892 toPos += 8;
893 }
894 writePos += toWidth8;
895 }
896
897 // AC1
898 writePos = 0;
899 for (size_t y=0; y<vBlockCount; ++y) {
900 int toPos = writePos;
901 for (size_t x=0; x<hBlockCount; ++x) {
902 to[toPos+toWidth*0+1] = *from++;
903 to[toPos+toWidth*1+0] = *from++;
904 to[toPos+toWidth*1+1] = *from++;
905 toPos += 8;
906 }
907 writePos += toWidth8;
908 }
909
910 // AC2
911 writePos = 0;
912 for (size_t y=0; y<vBlockCount; ++y) {
913 int toPos = writePos;
914 for (size_t x=0; x<hBlockCount; ++x) {
915 to[toPos+toWidth*0+2] = *from++;
916 to[toPos+toWidth*1+2] = *from++;
917 to[toPos+toWidth*2+0] = *from++;
918 to[toPos+toWidth*2+1] = *from++;
919 to[toPos+toWidth*2+2] = *from++;
920 toPos += 8;
921 }
922 writePos += toWidth8;
923 }
924
925 // AC3
926 writePos = 0;
927 for (size_t y=0; y<vBlockCount; ++y) {
928 int toPos = writePos;
929 for (size_t x=0; x<hBlockCount; ++x) {
930 to[toPos+toWidth*0+3] = *from++;
931 to[toPos+toWidth*1+3] = *from++;
932 to[toPos+toWidth*2+3] = *from++;
933 to[toPos+toWidth*3+0] = *from++;
934 to[toPos+toWidth*3+1] = *from++;
935 to[toPos+toWidth*3+2] = *from++;
936 to[toPos+toWidth*3+3] = *from++;
937 toPos += 8;
938 }
939 writePos += toWidth8;
940 }
941
942 // AC4
943 writePos = 0;
944 for (size_t y=0; y<vBlockCount; ++y) {
945 int toPos = writePos;
946 for (size_t x=0; x<hBlockCount; ++x) {
947 to[toPos+toWidth*0+4] = *from++;
948 to[toPos+toWidth*1+4] = *from++;
949 to[toPos+toWidth*2+4] = *from++;
950 to[toPos+toWidth*3+4] = *from++;
951 to[toPos+toWidth*4+0] = *from++;
952 to[toPos+toWidth*4+1] = *from++;
953 to[toPos+toWidth*4+2] = *from++;
954 to[toPos+toWidth*4+3] = *from++;
955 to[toPos+toWidth*4+4] = *from++;
956 toPos += 8;
957 }
958 writePos += toWidth8;
959 }
960
961 // AC5
962 writePos = 0;
963 for (size_t y=0; y<vBlockCount; ++y) {
964 int toPos = writePos;
965 for (size_t x=0; x<hBlockCount; ++x) {
966 to[toPos+toWidth*0+5] = *from++;
967 to[toPos+toWidth*1+5] = *from++;
968 to[toPos+toWidth*2+5] = *from++;
969 to[toPos+toWidth*3+5] = *from++;
970 to[toPos+toWidth*4+5] = *from++;
971 to[toPos+toWidth*5+0] = *from++;
972 to[toPos+toWidth*5+1] = *from++;
973 to[toPos+toWidth*5+2] = *from++;
974 to[toPos+toWidth*5+3] = *from++;
975 to[toPos+toWidth*5+4] = *from++;
976 to[toPos+toWidth*5+5] = *from++;
977 toPos += 8;
978 }
979 writePos += toWidth8;
980 }
981
982 // AC6
983 writePos = 0;
984 for (size_t y=0; y<vBlockCount; ++y) {
985 int toPos = writePos;
986 for (size_t x=0; x<hBlockCount; ++x) {
987 to[toPos+toWidth*0+6] = *from++;
988 to[toPos+toWidth*1+6] = *from++;
989 to[toPos+toWidth*2+6] = *from++;
990 to[toPos+toWidth*3+6] = *from++;
991 to[toPos+toWidth*4+6] = *from++;
992 to[toPos+toWidth*5+6] = *from++;
993 to[toPos+toWidth*6+0] = *from++;
994 to[toPos+toWidth*6+1] = *from++;
995 to[toPos+toWidth*6+2] = *from++;
996 to[toPos+toWidth*6+3] = *from++;
997 to[toPos+toWidth*6+4] = *from++;
998 to[toPos+toWidth*6+5] = *from++;
999 to[toPos+toWidth*6+6] = *from++;
1000 toPos += 8;
1001 }
1002 writePos += toWidth8;
1003 }
1004
1005 // AC7
1006 writePos = 0;
1007 for (size_t y=0; y<vBlockCount; ++y) {
1008 int toPos = writePos;
1009 for (size_t x=0; x<hBlockCount; ++x) {
1010 to[toPos+toWidth*0+7] = *from++;
1011 to[toPos+toWidth*1+7] = *from++;
1012 to[toPos+toWidth*2+7] = *from++;
1013 to[toPos+toWidth*3+7] = *from++;
1014 to[toPos+toWidth*4+7] = *from++;
1015 to[toPos+toWidth*5+7] = *from++;
1016 to[toPos+toWidth*6+7] = *from++;
1017 to[toPos+toWidth*7+0] = *from++;
1018 to[toPos+toWidth*7+1] = *from++;
1019 to[toPos+toWidth*7+2] = *from++;
1020 to[toPos+toWidth*7+3] = *from++;
1021 to[toPos+toWidth*7+4] = *from++;
1022 to[toPos+toWidth*7+5] = *from++;
1023 to[toPos+toWidth*7+6] = *from++;
1024 to[toPos+toWidth*7+7] = *from++;
1025 toPos += 8;
1026 }
1027 writePos += toWidth8;
1028 }
1029
1030 }
1031
1032 size_t decompress(
1033 size_t hBlockCount,
1034 size_t vBlockCount,
1035 const int* pZeroOneInfos,
1036 size_t zeroOneLimit,
1037 const unsigned char* src, size_t srcLen,
1038 unsigned char* tmp, int* tmp2,
1039 int* dest, size_t destLen
1040 )
1041 {
1042 const int totalBlockCount = static_cast<int>(hBlockCount * vBlockCount);
1043
1044 const unsigned char* from = src;
1045 int* to = dest;
1046
1047 for (size_t i=0; i<8; ++i) {
1048 const int* p01 = (i < zeroOneLimit) ? 0 : pZeroOneInfos;
1049 size_t blockSize = 1 + i * 2;
1050 from += decompressSub(from, p01, tmp, tmp2, to, totalBlockCount, blockSize);
1051 to += totalBlockCount * blockSize;
1052 }
1053
1054 return from - src;
1055 }
1056

Back to OSDN">Back to OSDN
ViewVC Help
Powered by ViewVC 1.1.26