Subversion Repositories Games.Descent

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. /*
  2.  * Portions of this file are copyright Rebirth contributors and licensed as
  3.  * described in COPYING.txt.
  4.  * Portions of this file are copyright Parallax Software and licensed
  5.  * according to the Parallax license below.
  6.  * See COPYING.txt for license details.
  7.  
  8. THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX
  9. SOFTWARE CORPORATION ("PARALLAX").  PARALLAX, IN DISTRIBUTING THE CODE TO
  10. END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A
  11. ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS
  12. IN USING, DISPLAYING,  AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS
  13. SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE
  14. FREE PURPOSES.  IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE
  15. CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES.  THE END-USER UNDERSTANDS
  16. AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE.
  17. COPYRIGHT 1993-1998 PARALLAX SOFTWARE CORPORATION.  ALL RIGHTS RESERVED.
  18. */
  19.  
  20. /*
  21.  *
  22.  * Routines to do run length encoding/decoding
  23.  * on bitmaps.
  24.  *
  25.  */
  26.  
  27. #include <algorithm>
  28. #include <stdlib.h>
  29. #include <stdio.h>
  30. #include <string.h>
  31.  
  32. #include "pstypes.h"
  33. #include "u_mem.h"
  34. #include "gr.h"
  35. #include "grdef.h"
  36. #include "dxxerror.h"
  37. #include "rle.h"
  38. #include "byteutil.h"
  39.  
  40. #include "compiler-range_for.h"
  41. #include "d_range.h"
  42.  
  43. namespace dcx {
  44.  
  45. constexpr uint8_t RLE_CODE = 0xe0;
  46. constexpr uint8_t NOT_RLE_CODE = 0x1f;
  47. static_assert((RLE_CODE | NOT_RLE_CODE) == 0xff, "RLE mask error");
  48. static inline int IS_RLE_CODE(const uint8_t &x)
  49. {
  50.         return (x & RLE_CODE) == RLE_CODE;
  51. }
  52. #define rle_stosb(_dest, _len, _color)  memset(_dest,_color,_len)
  53.  
  54. uint8_t *gr_rle_decode(const color_palette_index *sb, color_palette_index *db, const rle_position_t e)
  55. {
  56.         using std::advance;
  57.         using std::distance;
  58.         for (; sb != e.src;)
  59.         {
  60.                 auto p = sb;
  61.                 color_palette_index c;
  62.                 for (; c = *p, !IS_RLE_CODE(c);)
  63.                         if (++p == e.src)
  64.                                 return db;
  65.                 const size_t count = (c & NOT_RLE_CODE);
  66.                 const size_t cn = std::min<size_t>(distance(sb, p), distance(db, e.dst));
  67.                 memcpy(db, sb, cn);
  68.                 advance(db, cn);
  69.                 if (!count)
  70.                         break;
  71.                 advance(sb, cn);
  72.                 if (sb == e.src || db == e.dst || count > static_cast<size_t>(distance(db, e.dst)))
  73.                         break;
  74.                 if (++ sb == e.src)
  75.                         break;
  76.                 std::fill_n(db, count, *sb++);
  77.                 advance(db, count);
  78.         }
  79.         return db;
  80. }
  81.  
  82. #if !DXX_USE_OGL
  83. // Given pointer to start of one scanline of rle data, uncompress it to
  84. // dest, from source pixels x1 to x2.
  85. void gr_rle_expand_scanline_masked(uint8_t *dest, const uint8_t *src, int x1, int x2)
  86. {
  87.         int i = 0;
  88.         ubyte count;
  89.         ubyte color=0;
  90.  
  91.         if ( x2 < x1 ) return;
  92.  
  93.         count = 0;
  94.         while ( i < x1 )        {
  95.                 color = *src++;
  96.                 if ( color == RLE_CODE ) return;
  97.                 if ( IS_RLE_CODE(color) )       {
  98.                         count = color & NOT_RLE_CODE;
  99.                         color = *src++;
  100.                 } else {
  101.                         // unique
  102.                         count = 1;
  103.                 }
  104.                 i += count;
  105.         }
  106.         count = i - x1;
  107.         i = x1;
  108.         // we know have '*count' pixels of 'color'.
  109.        
  110.         if ( x1+count > x2 )    {
  111.                 count = x2-x1+1;
  112.                 if ( color != TRANSPARENCY_COLOR )      rle_stosb( dest, count, color );
  113.                 return;
  114.         }
  115.  
  116.         if ( color != TRANSPARENCY_COLOR )      rle_stosb( dest, count, color );
  117.         dest += count;
  118.         i += count;
  119.  
  120.         while( i <= x2 )
  121.         {
  122.                 color = *src++;
  123.                 if ( color == RLE_CODE ) return;
  124.                 if ( IS_RLE_CODE(color) )       {
  125.                         count = color & NOT_RLE_CODE;
  126.                         color = *src++;
  127.                 } else {
  128.                         // unique
  129.                         count = 1;
  130.                 }
  131.                 // we know have '*count' pixels of 'color'.
  132.                 if ( i+count <= x2 )    {
  133.                         if ( color != 255 )rle_stosb( dest, count, color );
  134.                         i += count;
  135.                         dest += count;
  136.                 } else {
  137.                         count = x2-i+1;
  138.                         if ( color != 255 )rle_stosb( dest, count, color );
  139.                         i += count;
  140.                         dest += count;
  141.                 }
  142.         }
  143. }
  144. #endif
  145.  
  146. void gr_rle_expand_scanline(uint8_t *dest, const uint8_t *src, int x1, int x2)
  147. {
  148.         int i = 0;
  149.         ubyte count;
  150.         ubyte color=0;
  151.  
  152.         if ( x2 < x1 ) return;
  153.  
  154.         count = 0;
  155.         while ( i < x1 )        {
  156.                 color = *src++;
  157.                 if ( color == RLE_CODE ) return;
  158.                 if ( IS_RLE_CODE(color) )       {
  159.                         count = color & NOT_RLE_CODE;
  160.                         color = *src++;
  161.                 } else {
  162.                         // unique
  163.                         count = 1;
  164.                 }
  165.                 i += count;
  166.         }
  167.         count = i - x1;
  168.         i = x1;
  169.         // we know have '*count' pixels of 'color'.
  170.        
  171.         if ( x1+count > x2 )    {
  172.                 count = x2-x1+1;
  173.                 rle_stosb( dest, count, color );
  174.                 return;
  175.         }
  176.  
  177.         rle_stosb( dest, count, color );
  178.         dest += count;
  179.         i += count;
  180.  
  181.         while( i <= x2 )                {
  182.                 color = *src++;
  183.                 if ( color == RLE_CODE ) return;
  184.                 if ( IS_RLE_CODE(color) )       {
  185.                         count = color & (~RLE_CODE);
  186.                         color = *src++;
  187.                 } else {
  188.                         // unique
  189.                         count = 1;
  190.                 }
  191.                 // we know have '*count' pixels of 'color'.
  192.                 if ( i+count <= x2 )    {
  193.                         rle_stosb( dest, count, color );
  194.                         i += count;
  195.                         dest += count;
  196.                 } else {
  197.                         count = x2-i+1;
  198.                         rle_stosb( dest, count, color );
  199.                         i += count;
  200.                         dest += count;
  201.                 }
  202.         }
  203. }
  204.  
  205. static std::ptrdiff_t gr_rle_encode( int org_size, const uint8_t *src, ubyte *dest )
  206. {
  207.         ubyte c, oc;
  208.         ubyte count;
  209.         uint8_t *dest_start;
  210.  
  211.         dest_start = dest;
  212.         oc = *src++;
  213.         count = 1;
  214.  
  215.         if (org_size > 0)
  216.         for (uint_fast32_t i = org_size; --i;)
  217.         {
  218.                 c = *src++;
  219.                 if ( c!=oc )    {
  220.                         if ( count )    {
  221.                                 if ( (count==1) && (! IS_RLE_CODE(oc)) )        {
  222.                                         *dest++ = oc;
  223.                                         Assert( oc != RLE_CODE );
  224.                                 } else {
  225.                                         count |= RLE_CODE;
  226.                                         *dest++ = count;
  227.                                         *dest++ = oc;
  228.                                 }
  229.                         }
  230.                         oc = c;
  231.                         count = 0;
  232.                 }
  233.                 count++;
  234.                 if ( count == NOT_RLE_CODE )    {
  235.                         count |= RLE_CODE;
  236.                         *dest++=count;
  237.                         *dest++=oc;
  238.                         count = 0;
  239.                 }
  240.         }
  241.         if (count)      {
  242.                 if ( (count==1) && (! IS_RLE_CODE(oc)) )        {
  243.                         *dest++ = oc;
  244.                         Assert( oc != RLE_CODE );
  245.                 } else {
  246.                         count |= RLE_CODE;
  247.                         *dest++ = count;
  248.                         *dest++ = oc;
  249.                 }
  250.         }
  251.         *dest++ = RLE_CODE;
  252.  
  253.         return dest-dest_start;
  254. }
  255.  
  256. static unsigned gr_rle_getsize(int org_size, const uint8_t *src)
  257. {
  258.         ubyte c, oc;
  259.         ubyte count;
  260.         int dest_size=0;
  261.  
  262.         oc = *src++;
  263.         count = 1;
  264.  
  265.         if (org_size > 0)
  266.         for (uint_fast32_t i = org_size; --i;)
  267.         {
  268.                 c = *src++;
  269.                 if ( c!=oc )    {
  270.                         if ( count )    {
  271.                                 if ( (count==1) && (! IS_RLE_CODE(oc)) )        {
  272.                                         dest_size++;
  273.                                 } else {
  274.                                         dest_size++;
  275.                                         dest_size++;
  276.                                 }
  277.                         }
  278.                         oc = c;
  279.                         count = 0;
  280.                 }
  281.                 count++;
  282.                 if ( count == NOT_RLE_CODE )    {
  283.                         dest_size++;
  284.                         dest_size++;
  285.                         count = 0;
  286.                 }
  287.         }
  288.         if (count)      {
  289.                 if ( (count==1) && (! IS_RLE_CODE(oc)) )        {
  290.                         dest_size++;
  291.                 } else {
  292.                         dest_size++;
  293.                         dest_size++;
  294.                 }
  295.         }
  296.         dest_size++;
  297.  
  298.         return dest_size;
  299. }
  300.  
  301. int gr_bitmap_rle_compress(grs_bitmap &bmp)
  302. {
  303.         int doffset;
  304.         int large_rle = 0;
  305.  
  306.         // first must check to see if this is large bitmap.
  307.  
  308.         const uint_fast32_t bm_h = bmp.bm_h;
  309.         const uint_fast32_t bm_w = bmp.bm_w;
  310.         range_for (const uint_fast32_t y, xrange(bm_h))
  311.         {
  312.                 auto d1 = gr_rle_getsize(bm_w, &bmp.get_bitmap_data()[bm_w * y]);
  313.                 if (d1 > 255) {
  314.                         large_rle = BM_FLAG_RLE_BIG;
  315.                         break;
  316.                 }
  317.         }
  318.  
  319.         RAIIdmem<uint8_t[]> rle_data;
  320.         MALLOC(rle_data, uint8_t[], MAX_BMP_SIZE(bm_w, bm_h));
  321.         if (!rle_data) return 0;
  322.         if (!large_rle)
  323.                 doffset = 4 + bm_h;
  324.         else
  325.                 doffset = 4 + (2 * bm_h);               // each row of rle'd bitmap has short instead of byte offset now
  326.  
  327.         range_for (const uint_fast32_t y, xrange(bm_h))
  328.         {
  329.                 auto d1 = gr_rle_getsize(bm_w, &bmp.get_bitmap_data()[bm_w * y]);
  330.                 if ( ((doffset+d1) > bmp.bm_w*bmp.bm_h) || (d1 > (large_rle?32767:255) ) ) {
  331.                         return 0;
  332.                 }
  333.                 const auto d = gr_rle_encode( bmp.bm_w, &bmp.get_bitmap_data()[bmp.bm_w*y], &rle_data[doffset] );
  334.                 Assert( d==d1 );
  335.                 doffset += d;
  336.                 if (large_rle)
  337.                         PUT_INTEL_SHORT(&rle_data[(y*2)+4], static_cast<short>(d));
  338.                 else
  339.                         rle_data[y+4] = d;
  340.         }
  341.         memcpy(bmp.get_bitmap_data(), &doffset, 4);
  342.         memcpy(&bmp.get_bitmap_data()[4], &rle_data.get()[4], doffset - 4);
  343.         bmp.add_flags(BM_FLAG_RLE | large_rle);
  344.         return 1;
  345. }
  346.  
  347. namespace {
  348.  
  349. struct rle_cache_element
  350. {
  351.         const grs_bitmap *rle_bitmap;
  352.         grs_bitmap_ptr expanded_bitmap;
  353.         int last_used;
  354. };
  355.  
  356. }
  357.  
  358. static int rle_cache_initialized;
  359. static int rle_counter;
  360. static int rle_next;
  361. static std::array<rle_cache_element, 32> rle_cache;
  362.  
  363. void rle_cache_close(void)
  364. {
  365.         if (rle_cache_initialized)      {
  366.                 rle_cache_initialized = 0;
  367.                 range_for (auto &i, rle_cache)
  368.                         i.expanded_bitmap.reset();
  369.         }
  370. }
  371.  
  372. static void rle_cache_init()
  373. {
  374.         rle_cache = {};
  375.         rle_cache_initialized = 1;
  376. }
  377.  
  378. void rle_cache_flush()
  379. {
  380.         range_for (auto &i, rle_cache)
  381.         {
  382.                 i.rle_bitmap = NULL;
  383.                 i.last_used = 0;
  384.         }
  385. }
  386.  
  387. static void rle_expand_texture_sub(const grs_bitmap &bmp, grs_bitmap &rle_temp_bitmap_1)
  388. {
  389.         auto sbits = &bmp.get_bitmap_data()[4 + bmp.bm_h];
  390.         auto dbits = rle_temp_bitmap_1.get_bitmap_data();
  391.  
  392.         rle_temp_bitmap_1.set_flags(bmp.get_flags() & (~BM_FLAG_RLE));
  393.  
  394.         for (int i=0; i < bmp.bm_h; i++ ) {
  395.                 gr_rle_decode(sbits, dbits, rle_end(bmp, rle_temp_bitmap_1));
  396.                 sbits += static_cast<int>(bmp.bm_data[4+i]);
  397.                 dbits += bmp.bm_w;
  398.         }
  399. }
  400.  
  401.  
  402. grs_bitmap *_rle_expand_texture(const grs_bitmap &bmp)
  403. {
  404.         int lowest_count, lc;
  405.  
  406.         if (!rle_cache_initialized) rle_cache_init();
  407.  
  408.         Assert(!(bmp.get_flag_mask(BM_FLAG_PAGED_OUT)));
  409.  
  410.         lc = rle_counter;
  411.         rle_counter++;
  412.  
  413.         if (rle_counter < 0)
  414.                 rle_counter = 0;
  415.        
  416.         if ( rle_counter < lc ) {
  417.                 rle_cache_flush();
  418.         }
  419.  
  420.         lowest_count = rle_cache[rle_next].last_used;
  421.         auto least_recently_used = &rle_cache[rle_next];
  422.         rle_next++;
  423.         if (rle_next >= rle_cache.size())
  424.                 rle_next = 0;
  425.  
  426.         range_for (auto &i, rle_cache)
  427.         {
  428.                 if (i.rle_bitmap == &bmp)
  429.                 {
  430.                         i.last_used = rle_counter;
  431.                         return i.expanded_bitmap.get();
  432.                 }
  433.                 if (i.last_used < lowest_count)
  434.                 {
  435.                         lowest_count = (least_recently_used = &i)->last_used;
  436.                 }
  437.         }
  438.  
  439.         least_recently_used->expanded_bitmap = gr_create_bitmap(bmp.bm_w, bmp.bm_h);
  440.         rle_expand_texture_sub(bmp, *least_recently_used->expanded_bitmap.get());
  441.         least_recently_used->rle_bitmap = &bmp;
  442.         least_recently_used->last_used = rle_counter;
  443.         return least_recently_used->expanded_bitmap.get();
  444. }
  445.  
  446. #if !DXX_USE_OGL
  447. void gr_rle_expand_scanline_generic(grs_canvas &canvas, grs_bitmap &dest, int dx, const int dy, const uint8_t *src, const int x1, const int x2)
  448. {
  449.         int i = 0;
  450.         int count;
  451.         ubyte color=0;
  452.  
  453.         if ( x2 < x1 ) return;
  454.  
  455.         count = 0;
  456.         while ( i < x1 )        {
  457.                 color = *src++;
  458.                 if ( color == RLE_CODE ) return;
  459.                 if ( IS_RLE_CODE(color) )       {
  460.                         count = color & NOT_RLE_CODE;
  461.                         color = *src++;
  462.                 } else {
  463.                         // unique
  464.                         count = 1;
  465.                 }
  466.                 i += count;
  467.         }
  468.         count = i - x1;
  469.         i = x1;
  470.         // we know have '*count' pixels of 'color'.
  471.  
  472.         if ( x1+count > x2 )    {
  473.                 count = x2-x1+1;
  474.                 for ( int j=0; j<count; j++ )
  475.                         gr_bm_pixel(canvas, dest, dx++, dy, color);
  476.                 return;
  477.         }
  478.  
  479.         for ( int j=0; j<count; j++ )
  480.                 gr_bm_pixel(canvas, dest, dx++, dy, color);
  481.         i += count;
  482.  
  483.         while( i <= x2 )                {
  484.                 color = *src++;
  485.                 if ( color == RLE_CODE ) return;
  486.                 if ( IS_RLE_CODE(color) )       {
  487.                         count = color & NOT_RLE_CODE;
  488.                         color = *src++;
  489.                 } else {
  490.                         // unique
  491.                         count = 1;
  492.                 }
  493.                 // we know have '*count' pixels of 'color'.
  494.                 if ( i+count <= x2 )    {
  495.                 } else {
  496.                         count = x2-i+1;
  497.                 }
  498.                 for (unsigned j = 0; j < count; ++j)
  499.                         gr_bm_pixel(canvas, dest, dx++, dy, color);
  500.                 i += count;
  501.         }
  502. }
  503. #endif
  504.  
  505. /*
  506.  * swaps entries 0 and 255 in an RLE bitmap without uncompressing it
  507.  */
  508. void rle_swap_0_255(grs_bitmap &bmp)
  509. {
  510.         int len, rle_big;
  511.         unsigned char *start;
  512.         unsigned short line_size;
  513.  
  514.         rle_big = bmp.get_flag_mask(BM_FLAG_RLE_BIG);
  515.  
  516.         RAIIdmem<uint8_t[]> temp;
  517.         MALLOC(temp, uint8_t[], MAX_BMP_SIZE(bmp.bm_w, bmp.bm_h));
  518.  
  519.         const std::size_t pointer_offset = rle_big ? 4 + 2 * bmp.bm_h : 4 + bmp.bm_h;
  520.         auto ptr = &bmp.bm_data[pointer_offset];
  521.         auto ptr2 = &temp[pointer_offset];
  522.         for (int i = 0; i < bmp.bm_h; i++) {
  523.                 start = ptr2;
  524.                 if (rle_big)
  525.                         line_size = GET_INTEL_SHORT(&bmp.bm_data[4 + 2 * i]);
  526.                 else
  527.                         line_size = bmp.bm_data[4 + i];
  528.                 for (int j = 0; j < line_size; j++) {
  529.                         if ( ! IS_RLE_CODE(ptr[j]) ) {
  530.                                 if (ptr[j] == 0) {
  531.                                         *ptr2++ = RLE_CODE | 1;
  532.                                         *ptr2++ = 255;
  533.                                 } else
  534.                                         *ptr2++ = ptr[j];
  535.                         } else {
  536.                                 *ptr2++ = ptr[j];
  537.                                 if ((ptr[j] & NOT_RLE_CODE) == 0)
  538.                                         break;
  539.                                 j++;
  540.                                 if (ptr[j] == 0)
  541.                                         *ptr2++ = 255;
  542.                                 else if (ptr[j] == 255)
  543.                                         *ptr2++ = 0;
  544.                                 else
  545.                                         *ptr2++ = ptr[j];
  546.                         }
  547.                 }
  548.                 if (rle_big)                // set line size
  549.                         PUT_INTEL_SHORT(&temp[4 + 2 * i], static_cast<uint16_t>(ptr2 - start));
  550.                 else
  551.                         temp[4 + i] = ptr2 - start;
  552.                 ptr += line_size;           // go to next line
  553.         }
  554.         len = ptr2 - temp.get();
  555.         memcpy(bmp.get_bitmap_data(), &len, 4);
  556.         memcpy(&bmp.get_bitmap_data()[4], &temp.get()[4], len - 4);
  557. }
  558.  
  559. /*
  560.  * remaps all entries using colormap in an RLE bitmap without uncompressing it
  561.  */
  562. void rle_remap(grs_bitmap &bmp, std::array<color_palette_index, 256> &colormap)
  563. {
  564.         int len, rle_big;
  565.         unsigned short line_size;
  566.  
  567.         rle_big = bmp.get_flag_mask(BM_FLAG_RLE_BIG);
  568.  
  569.         RAIIdmem<color_palette_index[]> temp;
  570.         MALLOC(temp, color_palette_index[], MAX_BMP_SIZE(bmp.bm_w, bmp.bm_h) + 30000);
  571.  
  572.         const std::size_t pointer_offset = rle_big ? 4 + 2 * bmp.bm_h : 4 + bmp.bm_h;
  573.         auto ptr = &bmp.get_bitmap_data()[pointer_offset];
  574.         auto ptr2 = &temp[pointer_offset];
  575.         for (int i = 0; i < bmp.bm_h; i++) {
  576.                 auto start = ptr2;
  577.                 if (rle_big)
  578.                         line_size = GET_INTEL_SHORT(&bmp.get_bitmap_data()[4 + 2 * i]);
  579.                 else
  580.                         line_size = bmp.get_bitmap_data()[4 + i];
  581.                 for (int j = 0; j < line_size; j++) {
  582.                         const uint8_t v = ptr[j];
  583.                         if (!IS_RLE_CODE(v))
  584.                         {
  585.                                 if (IS_RLE_CODE(colormap[v]))
  586.                                         *ptr2++ = color_palette_index{RLE_CODE | 1}; // add "escape sequence"
  587.                                 *ptr2++ = colormap[v]; // translate
  588.                         } else {
  589.                                 *ptr2++ = ptr[j]; // just copy current rle code
  590.                                 if ((ptr[j] & NOT_RLE_CODE) == 0)
  591.                                         break;
  592.                                 j++;
  593.                                 *ptr2++ = colormap[ptr[j]]; // translate
  594.                         }
  595.                 }
  596.                 if (rle_big)                // set line size
  597.                         PUT_INTEL_SHORT(&temp[4 + 2 * i], static_cast<uint16_t>(ptr2 - start));
  598.                 else
  599.                         temp[4 + i] = ptr2 - start;
  600.                 ptr += line_size;           // go to next line
  601.         }
  602.         len = ptr2 - temp.get();
  603.         memcpy(bmp.get_bitmap_data(), &len, 4);
  604.         memcpy(&bmp.get_bitmap_data()[4], &temp.get()[4], len - 4);
  605. }
  606.  
  607. void bm_rle_src_stride::advance_src_bits()
  608. {
  609.         /* Both bytes are always legal to read since the bitmap data
  610.          * is placed after the length table.  Reading both, then
  611.          * conditionally masking out the high bits (dependent on
  612.          * BM_FLAG_RLE_BIG) encourages the compiler to implement
  613.          * this line without using branches.
  614.          */
  615.         const uintptr_t u = (ptr_src_bit_lengths[0] | (static_cast<uintptr_t>(ptr_src_bit_lengths[1]) << 8)) & src_bit_load_mask;
  616.         ptr_src_bit_lengths += src_bit_stride_size;
  617.         src_bits += u;
  618. }
  619.  
  620. bm_rle_expand::step_result bm_rle_expand::step_internal(uint8_t *const begin_dbits, uint8_t *const end_dbits)
  621. {
  622.         const auto rd = gr_rle_decode(src_bits, begin_dbits, {end_src_bm, end_dbits});
  623.         /* If the destination buffer is exhausted, return without
  624.          * modifying the source state.  This lets the caller retry
  625.          * with a larger buffer, if desired.
  626.          */
  627.         if (unlikely(begin_dbits == rd))
  628.                 return dst_exhausted;
  629.         advance_src_bits();
  630.         return again;
  631. }
  632.  
  633. }
  634.