/*
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

/*****************************************************************************

 GIF construction tools

SPDX-License-Identifier: MIT

****************************************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "gif_lib.h"
#include "gif_lib_private.h"

#define MAX(x, y) (((x) > (y)) ? (x) : (y))

/******************************************************************************
 Miscellaneous utility functions
******************************************************************************/

/* return smallest bitfield size n will fit in */
int GifBitSize(int n) {
    register int i;

    for (i = 1; i <= 8; i++) {
        if ((1 << i) >= n) {
            break;
        }
    }
    return (i);
}

/******************************************************************************
 Color map object functions
******************************************************************************/

/*
 * Allocate a color map of given size; initialize with contents of
 * ColorMap if that pointer is non-NULL.
 */
ColorMapObject *GifMakeMapObject(int ColorCount, const GifColorType *ColorMap) {
    ColorMapObject *Object;

    /*** FIXME: Our ColorCount has to be a power of two.  Is it necessary to
     * make the user know that or should we automatically round up instead?
     */
    if (ColorCount != (1 << GifBitSize(ColorCount))) {
        return ((ColorMapObject *)NULL);
    }

    Object = (ColorMapObject *)malloc(sizeof(ColorMapObject));
    if (Object == (ColorMapObject *)NULL) {
        return ((ColorMapObject *)NULL);
    }

    Object->Colors =
        (GifColorType *)calloc(ColorCount, sizeof(GifColorType));
    if (Object->Colors == (GifColorType *)NULL) {
        free(Object);
        return ((ColorMapObject *)NULL);
    }

    Object->ColorCount = ColorCount;
    Object->BitsPerPixel = GifBitSize(ColorCount);
    Object->SortFlag = false;

    if (ColorMap != NULL) {
        memcpy((char *)Object->Colors, (char *)ColorMap,
               ColorCount * sizeof(GifColorType));
    }

    return (Object);
}

/*******************************************************************************
 Free a color map object
*******************************************************************************/
void GifFreeMapObject(ColorMapObject *Object) {
    if (Object != NULL) {
        (void)free(Object->Colors);
        (void)free(Object);
    }
}

#ifdef DEBUG
void DumpColorMap(ColorMapObject *Object, FILE *fp) {
    if (Object != NULL) {
        int i, j, Len = Object->ColorCount;

        for (i = 0; i < Len; i += 4) {
            for (j = 0; j < 4 && j < Len; j++) {
                (void)fprintf(fp, "%3d: %02x %02x %02x   ",
                              i + j, Object->Colors[i + j].Red,
                              Object->Colors[i + j].Green,
                              Object->Colors[i + j].Blue);
            }
            (void)fprintf(fp, "\n");
        }
    }
}
#endif /* DEBUG */

/*******************************************************************************
 Compute the union of two given color maps and return it.  If result can't
 fit into 256 colors, NULL is returned, the allocated union otherwise.
 ColorIn1 is copied as is to ColorUnion, while colors from ColorIn2 are
 copied iff they didn't exist before.  ColorTransIn2 maps the old
 ColorIn2 into the ColorUnion color map table./
*******************************************************************************/
ColorMapObject *GifUnionColorMap(const ColorMapObject *ColorIn1,
                                 const ColorMapObject *ColorIn2,
                                 GifPixelType ColorTransIn2[]) {
    int i, j, CrntSlot, RoundUpTo, NewGifBitSize;
    ColorMapObject *ColorUnion;

    /*
     * We don't worry about duplicates within either color map; if
     * the caller wants to resolve those, he can perform unions
     * with an empty color map.
     */

    /* Allocate table which will hold the result for sure. */
    ColorUnion = GifMakeMapObject(
        MAX(ColorIn1->ColorCount, ColorIn2->ColorCount) * 2, NULL);

    if (ColorUnion == NULL) {
        return (NULL);
    }

    /*
     * Copy ColorIn1 to ColorUnion.
     */
    for (i = 0; i < ColorIn1->ColorCount; i++) {
        ColorUnion->Colors[i] = ColorIn1->Colors[i];
    }
    CrntSlot = ColorIn1->ColorCount;

    /*
     * Potentially obnoxious hack:
     *
     * Back CrntSlot down past all contiguous {0, 0, 0} slots at the end
     * of table 1.  This is very useful if your display is limited to
     * 16 colors.
     */
    while (ColorIn1->Colors[CrntSlot - 1].Red == 0 &&
           ColorIn1->Colors[CrntSlot - 1].Green == 0 &&
           ColorIn1->Colors[CrntSlot - 1].Blue == 0) {
        CrntSlot--;
    }

    /* Copy ColorIn2 to ColorUnion (use old colors if they exist): */
    for (i = 0; i < ColorIn2->ColorCount && CrntSlot <= 256; i++) {
        /* Let's see if this color already exists: */
        for (j = 0; j < ColorIn1->ColorCount; j++) {
            if (memcmp(&ColorIn1->Colors[j], &ColorIn2->Colors[i],
                       sizeof(GifColorType)) == 0) {
                break;
            }
        }

        if (j < ColorIn1->ColorCount) {
            ColorTransIn2[i] = j; /* color exists in Color1 */
        } else {
            /* Color is new - copy it to a new slot: */
            ColorUnion->Colors[CrntSlot] = ColorIn2->Colors[i];
            ColorTransIn2[i] = CrntSlot++;
        }
    }

    if (CrntSlot > 256) {
        GifFreeMapObject(ColorUnion);
        return ((ColorMapObject *)NULL);
    }

    NewGifBitSize = GifBitSize(CrntSlot);
    RoundUpTo = (1 << NewGifBitSize);

    if (RoundUpTo != ColorUnion->ColorCount) {
        register GifColorType *Map = ColorUnion->Colors;

        /*
         * Zero out slots up to next power of 2.
         * We know these slots exist because of the way ColorUnion's
         * start dimension was computed.
         */
        for (j = CrntSlot; j < RoundUpTo; j++) {
            Map[j].Red = Map[j].Green = Map[j].Blue = 0;
        }

        /* perhaps we can shrink the map? */
        if (RoundUpTo < ColorUnion->ColorCount) {
            GifColorType *new_map = (GifColorType *)reallocarray(
                Map, RoundUpTo, sizeof(GifColorType));
            if (new_map == NULL) {
                GifFreeMapObject(ColorUnion);
                return ((ColorMapObject *)NULL);
            }
            ColorUnion->Colors = new_map;
        }
    }

    ColorUnion->ColorCount = RoundUpTo;
    ColorUnion->BitsPerPixel = NewGifBitSize;

    return (ColorUnion);
}

/*******************************************************************************
 Apply a given color translation to the raster bits of an image
*******************************************************************************/
void GifApplyTranslation(SavedImage *Image, const GifPixelType Translation[]) {
    register int i;
    register int RasterSize =
        Image->ImageDesc.Height * Image->ImageDesc.Width;

    for (i = 0; i < RasterSize; i++) {
        Image->RasterBits[i] = Translation[Image->RasterBits[i]];
    }
}

/******************************************************************************
 Extension record functions
******************************************************************************/
int GifAddExtensionBlock(int *ExtensionBlockCount,
                         ExtensionBlock **ExtensionBlocks, int Function,
                         unsigned int Len, unsigned char ExtData[]) {
    ExtensionBlock *ep;

    if (*ExtensionBlocks == NULL) {
        *ExtensionBlocks =
            (ExtensionBlock *)malloc(sizeof(ExtensionBlock));
    } else {
        ExtensionBlock *ep_new = (ExtensionBlock *)reallocarray(
            *ExtensionBlocks, (*ExtensionBlockCount + 1),
            sizeof(ExtensionBlock));
        if (ep_new == NULL) {
            return (GIF_ERROR);
        }
        *ExtensionBlocks = ep_new;
    }

    if (*ExtensionBlocks == NULL) {
        return (GIF_ERROR);
    }

    ep = &(*ExtensionBlocks)[(*ExtensionBlockCount)++];

    ep->Function = Function;
    ep->ByteCount = Len;
    ep->Bytes = (GifByteType *)malloc(ep->ByteCount);
    if (ep->Bytes == NULL) {
        return (GIF_ERROR);
    }

    if (ExtData != NULL) {
        memcpy(ep->Bytes, ExtData, Len);
    }

    return (GIF_OK);
}

void GifFreeExtensions(int *ExtensionBlockCount,
                       ExtensionBlock **ExtensionBlocks) {
    ExtensionBlock *ep;

    if (*ExtensionBlocks == NULL) {
        return;
    }

    for (ep = *ExtensionBlocks;
         ep < (*ExtensionBlocks + *ExtensionBlockCount); ep++) {
        (void)free((char *)ep->Bytes);
    }
    (void)free((char *)*ExtensionBlocks);
    *ExtensionBlocks = NULL;
    *ExtensionBlockCount = 0;
}

/******************************************************************************
   Image block allocation functions
******************************************************************************/

/* Private Function:
 * Frees the last image in the GifFile->SavedImages array
 */
void FreeLastSavedImage(GifFileType *GifFile) {
    SavedImage *sp;

    if ((GifFile == NULL) || (GifFile->SavedImages == NULL)) {
        return;
    }

    /* Remove one SavedImage from the GifFile */
    GifFile->ImageCount--;
    sp = &GifFile->SavedImages[GifFile->ImageCount];

    /* Deallocate its Colormap */
    if (sp->ImageDesc.ColorMap != NULL) {
        GifFreeMapObject(sp->ImageDesc.ColorMap);
        sp->ImageDesc.ColorMap = NULL;
    }

    /* Deallocate the image data */
    if (sp->RasterBits != NULL) {
        free((char *)sp->RasterBits);
    }

    /* Deallocate any extensions */
    GifFreeExtensions(&sp->ExtensionBlockCount, &sp->ExtensionBlocks);

    /*** FIXME: We could realloc the GifFile->SavedImages structure but is
     * there a point to it? Saves some memory but we'd have to do it every
     * time.  If this is used in GifFreeSavedImages then it would be
     * inefficient (The whole array is going to be deallocated.)  If we just
     * use it when we want to free the last Image it's convenient to do it
     * here.
     */
}

/*
 * Append an image block to the SavedImages array
 */
SavedImage *GifMakeSavedImage(GifFileType *GifFile,
                              const SavedImage *CopyFrom) {
    // cppcheck-suppress ctunullpointer
    if (GifFile->SavedImages == NULL) {
        GifFile->SavedImages = (SavedImage *)malloc(sizeof(SavedImage));
    } else {
        SavedImage *newSavedImages = (SavedImage *)reallocarray(
            GifFile->SavedImages, (GifFile->ImageCount + 1),
            sizeof(SavedImage));
        if (newSavedImages == NULL) {
            return ((SavedImage *)NULL);
        }
        GifFile->SavedImages = newSavedImages;
    }
    if (GifFile->SavedImages == NULL) {
        return ((SavedImage *)NULL);
    } else {
        SavedImage *sp = &GifFile->SavedImages[GifFile->ImageCount++];

        if (CopyFrom != NULL) {
            memcpy((char *)sp, CopyFrom, sizeof(SavedImage));

            /*
             * Make our own allocated copies of the heap fields in
             * the copied record.  This guards against potential
             * aliasing problems.
             */

            /* first, the local color map */
            if (CopyFrom->ImageDesc.ColorMap != NULL) {
                sp->ImageDesc.ColorMap = GifMakeMapObject(
                    CopyFrom->ImageDesc.ColorMap->ColorCount,
                    CopyFrom->ImageDesc.ColorMap->Colors);
                if (sp->ImageDesc.ColorMap == NULL) {
                    FreeLastSavedImage(GifFile);
                    return (SavedImage *)(NULL);
                }
            }

            /* next, the raster */
            sp->RasterBits = (unsigned char *)reallocarray(
                NULL,
                (CopyFrom->ImageDesc.Height *
                 CopyFrom->ImageDesc.Width),
                sizeof(GifPixelType));
            if (sp->RasterBits == NULL) {
                FreeLastSavedImage(GifFile);
                return (SavedImage *)(NULL);
            }
            memcpy(sp->RasterBits, CopyFrom->RasterBits,
                   sizeof(GifPixelType) *
                       CopyFrom->ImageDesc.Height *
                       CopyFrom->ImageDesc.Width);

            /* finally, the extension blocks */
            if (CopyFrom->ExtensionBlocks != NULL) {
                sp->ExtensionBlocks =
                    (ExtensionBlock *)reallocarray(
                        NULL, CopyFrom->ExtensionBlockCount,
                        sizeof(ExtensionBlock));
                if (sp->ExtensionBlocks == NULL) {
                    FreeLastSavedImage(GifFile);
                    return (SavedImage *)(NULL);
                }
                memcpy(sp->ExtensionBlocks,
                       CopyFrom->ExtensionBlocks,
                       sizeof(ExtensionBlock) *
                           CopyFrom->ExtensionBlockCount);
            }
        } else {
            memset((char *)sp, '\0', sizeof(SavedImage));
        }

        return (sp);
    }
}

void GifFreeSavedImages(GifFileType *GifFile) {
    SavedImage *sp;

    if ((GifFile == NULL) || (GifFile->SavedImages == NULL)) {
        return;
    }
    for (sp = GifFile->SavedImages;
         sp < GifFile->SavedImages + GifFile->ImageCount; sp++) {
        if (sp->ImageDesc.ColorMap != NULL) {
            GifFreeMapObject(sp->ImageDesc.ColorMap);
            sp->ImageDesc.ColorMap = NULL;
        }

        if (sp->RasterBits != NULL) {
            free((char *)sp->RasterBits);
        }

        GifFreeExtensions(&sp->ExtensionBlockCount,
                          &sp->ExtensionBlocks);
    }
    free((char *)GifFile->SavedImages);
    GifFile->SavedImages = NULL;
}

/* end */
