""" gifedit.py - Adjust contrast of a GIF by modifying its color palette.
Shouldn't touch anything but palette.
Usage:./gifedit.py input.gif contrast_factor
- input.gif: Path to the input GIF file. - contrast_factor: Floating point number where 1.0 is identity, >1.0 increases contrast, and <1.0 decreases contrast.
Output: A new GIF file with the contrast-adjusted palette, named after the input file with '_contrast_{factor}.gif' appended. """
import sys import os import struct
def adjust_contrast(rgb, factor): """ Apply contrast adjustment to a given RGB value.
:param rgb: The RGB value to adjust (as a tuple). :param factor: Contrast factor (1.0 = no change, >1.0 increase, <1.0 decrease). :return: Adjusted RGB value. """ r, g, b = rgb r = int(((r / 255.0 - 0.5) * factor + 0.5) * 255.0) g = int(((g / 255.0 - 0.5) * factor + 0.5) * 255.0) b = int(((b / 255.0 - 0.5) * factor + 0.5) * 255.0) return (max(0, min(255, r)), max(0, min(255, g)), max(0, min(255, b))) def main(): if len(sys.argv)!= 3: print("Usage:./gifedit.py input.gif contrast_factor") sys.exit(1)
input_file = sys.argv[1] try: contrast_factor = float(sys.argv[2]) except ValueError: print("Error: Contrast factor must be a floating point number.") sys.exit(1)
if contrast_factor <= 0: print("Warning: Contrast factor should be greater than zero. Proceeding with value:", contrast_factor)
# Load the GIF try: with open(input_file, 'rb') as f_in: gif_data = f_in.read()
# Verify the GIF magic bytes if gif_data[:6] not in [b'GIF87a', b'GIF89a']: print("Error: Not a GIF file.") sys.exit(1)
# Get the original file name without extension filename, file_extension = os.path.splitext(input_file) output_file = f"{filename}_contrast_{contrast_factor:.2f}{file_extension}"
# Extract and adjust the Global Color Table gct = gif_data[gct_start:gct_end] adjusted_gct = bytearray() for i in range(0, len(gct), 3): rgb = struct.unpack('<BBB', gct[i:i+3]) adjusted_rgb = adjust_contrast(rgb, contrast_factor) adjusted_gct.extend(adjusted_rgb)
# Replace the original GCT with the adjusted one gif_data = gif_data[:gct_start] + adjusted_gct + gif_data[gct_end:]
# Save the modified GIF data with open(output_file, 'wb') as f_out: f_out.write(gif_data) print(f"Output saved to: {output_file}")
except IOError as e: print(f"Error opening or processing the file: {e}")