Coverage Report

Created: 2025-06-13 06:08

/src/giflib-code/gif_hash.c
Line
Count
Source (jump to first uncovered line)
1
/*****************************************************************************
2
3
gif_hash.c -- module to support the following operations:
4
5
1. InitHashTable - initialize hash table.
6
2. ClearHashTable - clear the hash table to an empty state.
7
2. InsertHashTable - insert one item into data structure.
8
3. ExistsHashTable - test if item exists in data structure.
9
10
This module is used to hash the GIF codes during encoding.
11
12
*****************************************************************************/
13
// SPDX-License-Identifier: MIT
14
// SPDX-File-Copyright-Txt: (C) Copyright 1989 Gershon Elber
15
16
#include <fcntl.h>
17
#include <stdint.h>
18
#include <stdio.h>
19
#include <stdlib.h>
20
#include <string.h>
21
22
#include "gif_hash.h"
23
#include "gif_lib.h"
24
#include "gif_lib_private.h"
25
26
/* #define  DEBUG_HIT_RATE    Debug number of misses per hash Insert/Exists. */
27
28
#ifdef DEBUG_HIT_RATE
29
static long NumberOfTests = 0, NumberOfMisses = 0;
30
#endif /* DEBUG_HIT_RATE */
31
32
static int KeyItem(uint32_t Item);
33
34
/******************************************************************************
35
 Initialize HashTable - allocate the memory needed and clear it.        *
36
******************************************************************************/
37
350
GifHashTableType *_InitHashTable(void) {
38
350
  GifHashTableType *HashTable;
39
40
350
  if ((HashTable = (GifHashTableType *)malloc(
41
350
           sizeof(GifHashTableType))) == NULL) {
42
0
    return NULL;
43
0
  }
44
45
350
  _ClearHashTable(HashTable);
46
47
350
  return HashTable;
48
350
}
49
50
/******************************************************************************
51
 Routine to clear the HashTable to an empty state.            *
52
 This part is a little machine depended. Use the commented part otherwise.   *
53
******************************************************************************/
54
1.72k
void _ClearHashTable(GifHashTableType *HashTable) {
55
1.72k
  memset(HashTable->HTable, 0xFF, HT_SIZE * sizeof(uint32_t));
56
1.72k
}
57
58
/******************************************************************************
59
 Routine to insert a new Item into the HashTable. The data is assumed to be  *
60
 new one.                     *
61
******************************************************************************/
62
4.23M
void _InsertHashTable(GifHashTableType *HashTable, uint32_t Key, int Code) {
63
4.23M
  int HKey = KeyItem(Key);
64
4.23M
  uint32_t *HTable = HashTable->HTable;
65
66
#ifdef DEBUG_HIT_RATE
67
  NumberOfTests++;
68
  NumberOfMisses++;
69
#endif /* DEBUG_HIT_RATE */
70
71
7.34M
  while (HT_GET_KEY(HTable[HKey]) != 0xFFFFFL) {
72
#ifdef DEBUG_HIT_RATE
73
    NumberOfMisses++;
74
#endif /* DEBUG_HIT_RATE */
75
3.10M
    HKey = (HKey + 1) & HT_KEY_MASK;
76
3.10M
  }
77
4.23M
  HTable[HKey] = HT_PUT_KEY(Key) | HT_PUT_CODE(Code);
78
4.23M
}
79
80
/******************************************************************************
81
 Routine to test if given Key exists in HashTable and if so returns its code *
82
 Returns the Code if key was found, -1 if not.              *
83
******************************************************************************/
84
7.44M
int _ExistsHashTable(GifHashTableType *HashTable, uint32_t Key) {
85
7.44M
  int HKey = KeyItem(Key);
86
7.44M
  uint32_t *HTable = HashTable->HTable, HTKey;
87
88
#ifdef DEBUG_HIT_RATE
89
  NumberOfTests++;
90
  NumberOfMisses++;
91
#endif /* DEBUG_HIT_RATE */
92
93
11.4M
  while ((HTKey = HT_GET_KEY(HTable[HKey])) != 0xFFFFFL) {
94
#ifdef DEBUG_HIT_RATE
95
    NumberOfMisses++;
96
#endif /* DEBUG_HIT_RATE */
97
7.23M
    if (Key == HTKey) {
98
3.20M
      return HT_GET_CODE(HTable[HKey]);
99
3.20M
    }
100
4.02M
    HKey = (HKey + 1) & HT_KEY_MASK;
101
4.02M
  }
102
103
4.23M
  return -1;
104
7.44M
}
105
106
/******************************************************************************
107
 Routine to generate an HKey for the hashtable out of the given unique key.  *
108
 The given Key is assumed to be 20 bits as follows: lower 8 bits are the     *
109
 new postfix character, while the upper 12 bits are the prefix code.        *
110
 Because the average hit ratio is only 2 (2 hash references per entry),      *
111
 evaluating more complex keys (such as twin prime keys) does not worth it!   *
112
******************************************************************************/
113
11.6M
static int KeyItem(uint32_t Item) {
114
11.6M
  return ((Item >> 12) ^ Item) & HT_KEY_MASK;
115
11.6M
}
116
117
#ifdef DEBUG_HIT_RATE
118
/******************************************************************************
119
 Debugging routine to print the hit ratio - number of times the hash table   *
120
 was tested per operation. This routine was used to test the KeyItem routine *
121
******************************************************************************/
122
void HashTablePrintHitRatio(void) {
123
  printf("Hash Table Hit Ratio is %ld/%ld = %ld%%.\n", NumberOfMisses,
124
         NumberOfTests, NumberOfMisses * 100 / NumberOfTests);
125
}
126
#endif /* DEBUG_HIT_RATE */
127
128
/* end */