/*
 *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license 
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may 
 *  be found in the AUTHORS file in the root of the source tree.
 */


/* This code is in the public domain.
** Version: 1.1  Author: Walt Karas
*/

#include "hmm_intrnl.h"

void U(shrink_chunk)(U(descriptor) *desc, U(size_bau) n_baus_to_shrink)
{
    head_record *dummy_end_block = (head_record *)
                                   BAUS_BACKWARD(desc->end_of_shrinkable_chunk, DUMMY_END_BLOCK_BAUS);

#ifdef HMM_AUDIT_FAIL

    if (dummy_end_block->block_size != 0)
        /* Chunk does not have valid dummy end block. */
        HMM_AUDIT_FAIL

#endif

        if (n_baus_to_shrink)
        {
            head_record *last_block = (head_record *)
                                      BAUS_BACKWARD(
                                          dummy_end_block, dummy_end_block->previous_block_size);

#ifdef HMM_AUDIT_FAIL
            AUDIT_BLOCK(last_block)
#endif

            if (last_block == desc->last_freed)
            {
                U(size_bau) bs = BLOCK_BAUS(last_block);

                /* Chunk will not be shrunk out of existence if
                ** 1.  There is at least one allocated block in the chunk
                **     and the amount to shrink is exactly the size of the
                **     last block, OR
                ** 2.  After the last block is shrunk, there will be enough
                **     BAUs left in it to form a minimal size block. */
                int chunk_will_survive =
                    (PREV_BLOCK_BAUS(last_block) && (n_baus_to_shrink == bs)) ||
                    (n_baus_to_shrink <= (U(size_bau))(bs - MIN_BLOCK_BAUS));

                if (chunk_will_survive ||
                    (!PREV_BLOCK_BAUS(last_block) &&
                     (n_baus_to_shrink ==
                      (U(size_bau))(bs + DUMMY_END_BLOCK_BAUS))))
                {
                    desc->last_freed = 0;

                    if (chunk_will_survive)
                    {
                        bs -= n_baus_to_shrink;

                        if (bs)
                        {
                            /* The last (non-dummy) block was not completely
                            ** eliminated by the shrink. */

                            last_block->block_size = bs;

                            /* Create new dummy end record.
                            */
                            dummy_end_block =
                                (head_record *) BAUS_FORWARD(last_block, bs);
                            dummy_end_block->previous_block_size = bs;
                            dummy_end_block->block_size = 0;

#ifdef HMM_AUDIT_FAIL

                            if (desc->avl_tree_root)
                                AUDIT_BLOCK(PTR_REC_TO_HEAD(desc->avl_tree_root))
#endif

                                U(into_free_collection)(desc, last_block);
                        }
                        else
                        {
                            /* The last (non-dummy) block was completely
                            ** eliminated by the shrink.  Make its head
                            ** the new dummy end block.
                            */
                            last_block->block_size = 0;
                            last_block->previous_block_size &= ~HIGH_BIT_BAU_SIZE;
                        }
                    }
                }

#ifdef HMM_AUDIT_FAIL
                else
                    HMM_AUDIT_FAIL
#endif
                }

#ifdef HMM_AUDIT_FAIL
            else
                HMM_AUDIT_FAIL
#endif
            }
}
