| OLD | NEW | 
|---|
| 1 | 1 | 
| 2 /* | 2 /* | 
| 3  * Copyright 2011 Google Inc. | 3  * Copyright 2011 Google Inc. | 
| 4  * | 4  * | 
| 5  * Use of this source code is governed by a BSD-style license that can be | 5  * Use of this source code is governed by a BSD-style license that can be | 
| 6  * found in the LICENSE file. | 6  * found in the LICENSE file. | 
| 7  */ | 7  */ | 
| 8 #include "SkPackBits.h" | 8 #include "SkPackBits.h" | 
| 9 | 9 | 
| 10 #define GATHER_STATSx | 10 #define GATHER_STATSx | 
| 11 | 11 | 
| 12 static inline void small_memcpy(void* SK_RESTRICT dst, | 12 static inline void small_memcpy(void* SK_RESTRICT dst, | 
| 13                                 const void* SK_RESTRICT src, int n) { | 13                                 const void* SK_RESTRICT src, size_t n) { | 
| 14     SkASSERT(n > 0 && n <= 15); | 14     SkASSERT(n > 0 && n <= 15); | 
| 15     uint8_t* d = (uint8_t*)dst; | 15     uint8_t* d = (uint8_t*)dst; | 
| 16     const uint8_t* s = (const uint8_t*)src; | 16     const uint8_t* s = (const uint8_t*)src; | 
| 17     switch (n) { | 17     switch (n) { | 
| 18         case 15: *d++ = *s++; | 18         case 15: *d++ = *s++; | 
| 19         case 14: *d++ = *s++; | 19         case 14: *d++ = *s++; | 
| 20         case 13: *d++ = *s++; | 20         case 13: *d++ = *s++; | 
| 21         case 12: *d++ = *s++; | 21         case 12: *d++ = *s++; | 
| 22         case 11: *d++ = *s++; | 22         case 11: *d++ = *s++; | 
| 23         case 10: *d++ = *s++; | 23         case 10: *d++ = *s++; | 
| 24         case  9: *d++ = *s++; | 24         case  9: *d++ = *s++; | 
| 25         case  8: *d++ = *s++; | 25         case  8: *d++ = *s++; | 
| 26         case  7: *d++ = *s++; | 26         case  7: *d++ = *s++; | 
| 27         case  6: *d++ = *s++; | 27         case  6: *d++ = *s++; | 
| 28         case  5: *d++ = *s++; | 28         case  5: *d++ = *s++; | 
| 29         case  4: *d++ = *s++; | 29         case  4: *d++ = *s++; | 
| 30         case  3: *d++ = *s++; | 30         case  3: *d++ = *s++; | 
| 31         case  2: *d++ = *s++; | 31         case  2: *d++ = *s++; | 
| 32         case  1: *d++ = *s++; | 32         case  1: *d++ = *s++; | 
| 33         case  0: break; | 33         case  0: break; | 
| 34     } | 34     } | 
| 35 } | 35 } | 
| 36 | 36 | 
| 37 static inline void small_memset(void* dst, uint8_t value, int n) { | 37 static inline void small_memset(void* dst, uint8_t value, size_t n) { | 
| 38     SkASSERT(n > 0 && n <= 15); | 38     SkASSERT(n > 0 && n <= 15); | 
| 39     uint8_t* d = (uint8_t*)dst; | 39     uint8_t* d = (uint8_t*)dst; | 
| 40     switch (n) { | 40     switch (n) { | 
| 41         case 15: *d++ = value; | 41         case 15: *d++ = value; | 
| 42         case 14: *d++ = value; | 42         case 14: *d++ = value; | 
| 43         case 13: *d++ = value; | 43         case 13: *d++ = value; | 
| 44         case 12: *d++ = value; | 44         case 12: *d++ = value; | 
| 45         case 11: *d++ = value; | 45         case 11: *d++ = value; | 
| 46         case 10: *d++ = value; | 46         case 10: *d++ = value; | 
| 47         case  9: *d++ = value; | 47         case  9: *d++ = value; | 
| (...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 189     } | 189     } | 
| 190     return dst; | 190     return dst; | 
| 191 } | 191 } | 
| 192 | 192 | 
| 193 size_t SkPackBits::Pack16(const uint16_t* SK_RESTRICT src, int count, | 193 size_t SkPackBits::Pack16(const uint16_t* SK_RESTRICT src, int count, | 
| 194                           uint8_t* SK_RESTRICT dst) { | 194                           uint8_t* SK_RESTRICT dst) { | 
| 195     uint8_t* origDst = dst; | 195     uint8_t* origDst = dst; | 
| 196     const uint16_t* stop = src + count; | 196     const uint16_t* stop = src + count; | 
| 197 | 197 | 
| 198     for (;;) { | 198     for (;;) { | 
| 199         count = stop - src; | 199         count = SkToInt(stop - src); | 
| 200         SkASSERT(count >= 0); | 200         SkASSERT(count >= 0); | 
| 201         if (count == 0) { | 201         if (count == 0) { | 
| 202             return dst - origDst; | 202             return dst - origDst; | 
| 203         } | 203         } | 
| 204         if (1 == count) { | 204         if (1 == count) { | 
| 205             *dst++ = 0; | 205             *dst++ = 0; | 
| 206             *dst++ = (uint8_t)(*src >> 8); | 206             *dst++ = (uint8_t)(*src >> 8); | 
| 207             *dst++ = (uint8_t)*src; | 207             *dst++ = (uint8_t)*src; | 
| 208             return dst - origDst; | 208             return dst - origDst; | 
| 209         } | 209         } | 
| 210 | 210 | 
| 211         unsigned value = *src; | 211         unsigned value = *src; | 
| 212         const uint16_t* s = src + 1; | 212         const uint16_t* s = src + 1; | 
| 213 | 213 | 
| 214         if (*s == value) { // accumulate same values... | 214         if (*s == value) { // accumulate same values... | 
| 215             do { | 215             do { | 
| 216                 s++; | 216                 s++; | 
| 217                 if (s == stop) { | 217                 if (s == stop) { | 
| 218                     break; | 218                     break; | 
| 219                 } | 219                 } | 
| 220             } while (*s == value); | 220             } while (*s == value); | 
| 221             dst = flush_same16(dst, value, s - src); | 221             dst = flush_same16(dst, value, SkToInt(s - src)); | 
| 222         } else {    // accumulate diff values... | 222         } else {    // accumulate diff values... | 
| 223             do { | 223             do { | 
| 224                 if (++s == stop) { | 224                 if (++s == stop) { | 
| 225                     goto FLUSH_DIFF; | 225                     goto FLUSH_DIFF; | 
| 226                 } | 226                 } | 
| 227             } while (*s != s[-1]); | 227             } while (*s != s[-1]); | 
| 228             s -= 1; // back up so we don't grab one of the "same" values that fo
     llow | 228             s -= 1; // back up so we don't grab one of the "same" values that fo
     llow | 
| 229         FLUSH_DIFF: | 229         FLUSH_DIFF: | 
| 230             dst = flush_diff16(dst, src, s - src); | 230             dst = flush_diff16(dst, src, SkToInt(s - src)); | 
| 231         } | 231         } | 
| 232         src = s; | 232         src = s; | 
| 233     } | 233     } | 
| 234 } | 234 } | 
| 235 | 235 | 
| 236 size_t SkPackBits::Pack8(const uint8_t* SK_RESTRICT src, int count, | 236 size_t SkPackBits::Pack8(const uint8_t* SK_RESTRICT src, int count, | 
| 237                          uint8_t* SK_RESTRICT dst) { | 237                          uint8_t* SK_RESTRICT dst) { | 
| 238     uint8_t* origDst = dst; | 238     uint8_t* origDst = dst; | 
| 239     const uint8_t* stop = src + count; | 239     const uint8_t* stop = src + count; | 
| 240 | 240 | 
| 241     for (;;) { | 241     for (;;) { | 
| 242         count = stop - src; | 242         count = SkToInt(stop - src); | 
| 243         SkASSERT(count >= 0); | 243         SkASSERT(count >= 0); | 
| 244         if (count == 0) { | 244         if (count == 0) { | 
| 245             return dst - origDst; | 245             return dst - origDst; | 
| 246         } | 246         } | 
| 247         if (1 == count) { | 247         if (1 == count) { | 
| 248             *dst++ = 0; | 248             *dst++ = 0; | 
| 249             *dst++ = *src; | 249             *dst++ = *src; | 
| 250             return dst - origDst; | 250             return dst - origDst; | 
| 251         } | 251         } | 
| 252 | 252 | 
| 253         unsigned value = *src; | 253         unsigned value = *src; | 
| 254         const uint8_t* s = src + 1; | 254         const uint8_t* s = src + 1; | 
| 255 | 255 | 
| 256         if (*s == value) { // accumulate same values... | 256         if (*s == value) { // accumulate same values... | 
| 257             do { | 257             do { | 
| 258                 s++; | 258                 s++; | 
| 259                 if (s == stop) { | 259                 if (s == stop) { | 
| 260                     break; | 260                     break; | 
| 261                 } | 261                 } | 
| 262             } while (*s == value); | 262             } while (*s == value); | 
| 263             dst = flush_same8(dst, value, s - src); | 263             dst = flush_same8(dst, value, SkToInt(s - src)); | 
| 264         } else {    // accumulate diff values... | 264         } else {    // accumulate diff values... | 
| 265             do { | 265             do { | 
| 266                 if (++s == stop) { | 266                 if (++s == stop) { | 
| 267                     goto FLUSH_DIFF; | 267                     goto FLUSH_DIFF; | 
| 268                 } | 268                 } | 
| 269                 // only stop if we hit 3 in a row, | 269                 // only stop if we hit 3 in a row, | 
| 270                 // otherwise we get bigger than compuatemax | 270                 // otherwise we get bigger than compuatemax | 
| 271             } while (*s != s[-1] || s[-1] != s[-2]); | 271             } while (*s != s[-1] || s[-1] != s[-2]); | 
| 272             s -= 2; // back up so we don't grab the "same" values that follow | 272             s -= 2; // back up so we don't grab the "same" values that follow | 
| 273         FLUSH_DIFF: | 273         FLUSH_DIFF: | 
| 274             dst = flush_diff8(dst, src, s - src); | 274             dst = flush_diff8(dst, src, SkToInt(s - src)); | 
| 275         } | 275         } | 
| 276         src = s; | 276         src = s; | 
| 277     } | 277     } | 
| 278 } | 278 } | 
| 279 | 279 | 
| 280 #include "SkUtils.h" | 280 #include "SkUtils.h" | 
| 281 | 281 | 
| 282 int SkPackBits::Unpack16(const uint8_t* SK_RESTRICT src, size_t srcSize, | 282 int SkPackBits::Unpack16(const uint8_t* SK_RESTRICT src, size_t srcSize, | 
| 283                          uint16_t* SK_RESTRICT dst) { | 283                          uint16_t* SK_RESTRICT dst) { | 
| 284     uint16_t* origDst = dst; | 284     uint16_t* origDst = dst; | 
| 285     const uint8_t* stop = src + srcSize; | 285     const uint8_t* stop = src + srcSize; | 
| 286 | 286 | 
| 287     while (src < stop) { | 287     while (src < stop) { | 
| 288         unsigned n = *src++; | 288         unsigned n = *src++; | 
| 289         if (n <= 127) {   // repeat count (n + 1) | 289         if (n <= 127) {   // repeat count (n + 1) | 
| 290             n += 1; | 290             n += 1; | 
| 291             sk_memset16(dst, (src[0] << 8) | src[1], n); | 291             sk_memset16(dst, (src[0] << 8) | src[1], n); | 
| 292             src += 2; | 292             src += 2; | 
| 293         } else {    // same count (n - 127) | 293         } else {    // same count (n - 127) | 
| 294             n -= 127; | 294             n -= 127; | 
| 295             PB_MEMCPY(dst, src, n * sizeof(uint16_t)); | 295             PB_MEMCPY(dst, src, n * sizeof(uint16_t)); | 
| 296             src += n * sizeof(uint16_t); | 296             src += n * sizeof(uint16_t); | 
| 297         } | 297         } | 
| 298         dst += n; | 298         dst += n; | 
| 299     } | 299     } | 
| 300     SkASSERT(src == stop); | 300     SkASSERT(src == stop); | 
| 301     return dst - origDst; | 301     return SkToInt(dst - origDst); | 
| 302 } | 302 } | 
| 303 | 303 | 
| 304 int SkPackBits::Unpack8(const uint8_t* SK_RESTRICT src, size_t srcSize, | 304 int SkPackBits::Unpack8(const uint8_t* SK_RESTRICT src, size_t srcSize, | 
| 305                         uint8_t* SK_RESTRICT dst) { | 305                         uint8_t* SK_RESTRICT dst) { | 
| 306     uint8_t* origDst = dst; | 306     uint8_t* origDst = dst; | 
| 307     const uint8_t* stop = src + srcSize; | 307     const uint8_t* stop = src + srcSize; | 
| 308 | 308 | 
| 309     while (src < stop) { | 309     while (src < stop) { | 
| 310         unsigned n = *src++; | 310         unsigned n = *src++; | 
| 311         if (n <= 127) {   // repeat count (n + 1) | 311         if (n <= 127) {   // repeat count (n + 1) | 
| 312             n += 1; | 312             n += 1; | 
| 313             PB_MEMSET(dst, *src++, n); | 313             PB_MEMSET(dst, *src++, n); | 
| 314         } else {    // same count (n - 127) | 314         } else {    // same count (n - 127) | 
| 315             n -= 127; | 315             n -= 127; | 
| 316             PB_MEMCPY(dst, src, n); | 316             PB_MEMCPY(dst, src, n); | 
| 317             src += n; | 317             src += n; | 
| 318         } | 318         } | 
| 319         dst += n; | 319         dst += n; | 
| 320     } | 320     } | 
| 321     SkASSERT(src == stop); | 321     SkASSERT(src == stop); | 
| 322     return dst - origDst; | 322     return SkToInt(dst - origDst); | 
| 323 } | 323 } | 
| 324 | 324 | 
| 325 enum UnpackState { | 325 enum UnpackState { | 
| 326     CLEAN_STATE, | 326     CLEAN_STATE, | 
| 327     REPEAT_BYTE_STATE, | 327     REPEAT_BYTE_STATE, | 
| 328     COPY_SRC_STATE | 328     COPY_SRC_STATE | 
| 329 }; | 329 }; | 
| 330 | 330 | 
| 331 void SkPackBits::Unpack8(uint8_t* SK_RESTRICT dst, size_t dstSkip, | 331 void SkPackBits::Unpack8(uint8_t* SK_RESTRICT dst, size_t dstSkip, | 
| 332                          size_t dstWrite, const uint8_t* SK_RESTRICT src) { | 332                          size_t dstWrite, const uint8_t* SK_RESTRICT src) { | 
| 333     if (dstWrite == 0) { | 333     if (dstWrite == 0) { | 
| 334         return; | 334         return; | 
| 335     } | 335     } | 
| 336 | 336 | 
| 337     UnpackState state = CLEAN_STATE; | 337     UnpackState state = CLEAN_STATE; | 
| 338     size_t      stateCount = 0; | 338     size_t      stateCount = 0; | 
| 339 | 339 | 
| 340     // state 1: do the skip-loop | 340     // state 1: do the skip-loop | 
| 341     while (dstSkip > 0) { | 341     while (dstSkip > 0) { | 
| 342         unsigned n = *src++; | 342         size_t n = *src++; | 
| 343         if (n <= 127) {   // repeat count (n + 1) | 343         if (n <= 127) {   // repeat count (n + 1) | 
| 344             n += 1; | 344             n += 1; | 
| 345             if (n > dstSkip) { | 345             if (n > dstSkip) { | 
| 346                 state = REPEAT_BYTE_STATE; | 346                 state = REPEAT_BYTE_STATE; | 
| 347                 stateCount = n - dstSkip; | 347                 stateCount = n - dstSkip; | 
| 348                 n = dstSkip; | 348                 n = dstSkip; | 
| 349                 // we don't increment src here, since its needed in stage 2 | 349                 // we don't increment src here, since its needed in stage 2 | 
| 350             } else { | 350             } else { | 
| 351                 src++;  // skip the src byte | 351                 src++;  // skip the src byte | 
| 352             } | 352             } | 
| (...skipping 27 matching lines...) Expand all  Loading... | 
| 380             break; | 380             break; | 
| 381         default: | 381         default: | 
| 382             SkASSERT(stateCount == 0); | 382             SkASSERT(stateCount == 0); | 
| 383             break; | 383             break; | 
| 384     } | 384     } | 
| 385     dst += stateCount; | 385     dst += stateCount; | 
| 386     dstWrite -= stateCount; | 386     dstWrite -= stateCount; | 
| 387 | 387 | 
| 388     // copy at most dstWrite bytes into dst[] | 388     // copy at most dstWrite bytes into dst[] | 
| 389     while (dstWrite > 0) { | 389     while (dstWrite > 0) { | 
| 390         unsigned n = *src++; | 390         size_t n = *src++; | 
| 391         if (n <= 127) {   // repeat count (n + 1) | 391         if (n <= 127) {   // repeat count (n + 1) | 
| 392             n += 1; | 392             n += 1; | 
| 393             if (n > dstWrite) { | 393             if (n > dstWrite) { | 
| 394                 n = dstWrite; | 394                 n = dstWrite; | 
| 395             } | 395             } | 
| 396             register_memset_count(n); | 396             register_memset_count(n); | 
| 397             PB_MEMSET(dst, *src++, n); | 397             PB_MEMSET(dst, *src++, n); | 
| 398         } else {    // same count (n - 127) | 398         } else {    // same count (n - 127) | 
| 399             n -= 127; | 399             n -= 127; | 
| 400             if (n > dstWrite) { | 400             if (n > dstWrite) { | 
| 401                 n = dstWrite; | 401                 n = dstWrite; | 
| 402             } | 402             } | 
| 403             register_memcpy_count(n); | 403             register_memcpy_count(n); | 
| 404             PB_MEMCPY(dst, src, n); | 404             PB_MEMCPY(dst, src, n); | 
| 405             src += n; | 405             src += n; | 
| 406         } | 406         } | 
| 407         dst += n; | 407         dst += n; | 
| 408         dstWrite -= n; | 408         dstWrite -= n; | 
| 409     } | 409     } | 
| 410     SkASSERT(0 == dstWrite); | 410     SkASSERT(0 == dstWrite); | 
| 411 } | 411 } | 
| OLD | NEW | 
|---|