xref: /aosp_15_r20/external/zopfli/go/zopflipng/zopflipng.go (revision e47783fd9ac7e78d0523d35be12ee382df490d63)
1*e47783fdSXin Li// Copyright 2019 Google LLC
2*e47783fdSXin Li//
3*e47783fdSXin Li// Licensed under the Apache License, Version 2.0 (the "License");
4*e47783fdSXin Li// you may not use this file except in compliance with the License.
5*e47783fdSXin Li// You may obtain a copy of the License at
6*e47783fdSXin Li//
7*e47783fdSXin Li//     https://www.apache.org/licenses/LICENSE-2.0
8*e47783fdSXin Li//
9*e47783fdSXin Li// Unless required by applicable law or agreed to in writing, software
10*e47783fdSXin Li// distributed under the License is distributed on an "AS IS" BASIS,
11*e47783fdSXin Li// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*e47783fdSXin Li// See the License for the specific language governing permissions and
13*e47783fdSXin Li// limitations under the License.
14*e47783fdSXin Lipackage zopflipng
15*e47783fdSXin Li
16*e47783fdSXin Liimport (
17*e47783fdSXin Li	"fmt"
18*e47783fdSXin Li)
19*e47783fdSXin Li
20*e47783fdSXin Li/*
21*e47783fdSXin Li#cgo LDFLAGS: -lzopflipng -lzopfli -lstdc++ -lm
22*e47783fdSXin Li#include <stdlib.h>
23*e47783fdSXin Li#include <string.h>
24*e47783fdSXin Li#include "zopflipng_lib.h"
25*e47783fdSXin Li*/
26*e47783fdSXin Liimport "C"
27*e47783fdSXin Liimport "unsafe"
28*e47783fdSXin Li
29*e47783fdSXin Li// Options allows overriding of some internal parameters.
30*e47783fdSXin Litype Options struct {
31*e47783fdSXin Li	LossyTransparent   bool
32*e47783fdSXin Li	Lossy8bit          bool
33*e47783fdSXin Li	NumIterations      int
34*e47783fdSXin Li	NumIterationsLarge int
35*e47783fdSXin Li}
36*e47783fdSXin Li
37*e47783fdSXin Li// NewOptions creates an options struct with the default parameters.
38*e47783fdSXin Lifunc NewOptions() *Options {
39*e47783fdSXin Li	ret := &Options{
40*e47783fdSXin Li		LossyTransparent:   false,
41*e47783fdSXin Li		Lossy8bit:          false,
42*e47783fdSXin Li		NumIterations:      15,
43*e47783fdSXin Li		NumIterationsLarge: 5,
44*e47783fdSXin Li	}
45*e47783fdSXin Li	return ret
46*e47783fdSXin Li}
47*e47783fdSXin Li
48*e47783fdSXin Li// Compress recompresses a PNG using Zopfli.
49*e47783fdSXin Lifunc Compress(inputSlice []byte) ([]byte, error) {
50*e47783fdSXin Li	return CompressWithOptions(inputSlice, NewOptions())
51*e47783fdSXin Li}
52*e47783fdSXin Li
53*e47783fdSXin Li// CompressWithOptions allows overriding some internal parameters.
54*e47783fdSXin Lifunc CompressWithOptions(inputSlice []byte, options *Options) ([]byte, error) {
55*e47783fdSXin Li	cOptions := createCOptions(options)
56*e47783fdSXin Li	input := (*C.uchar)(unsafe.Pointer(&inputSlice[0]))
57*e47783fdSXin Li	inputSize := (C.size_t)(len(inputSlice))
58*e47783fdSXin Li	var compressed *C.uchar
59*e47783fdSXin Li	var compressedLength C.size_t
60*e47783fdSXin Li	errCode := int(C.CZopfliPNGOptimize(input, inputSize, &cOptions, 0, &compressed, &compressedLength))
61*e47783fdSXin Li	defer C.free(unsafe.Pointer(compressed))
62*e47783fdSXin Li	if errCode != 0 {
63*e47783fdSXin Li		return nil, fmt.Errorf("ZopfliPng failed with code: %d", errCode)
64*e47783fdSXin Li	}
65*e47783fdSXin Li
66*e47783fdSXin Li	result := make([]byte, compressedLength)
67*e47783fdSXin Li	C.memmove(unsafe.Pointer(&result[0]), unsafe.Pointer(compressed), compressedLength)
68*e47783fdSXin Li	return result, nil
69*e47783fdSXin Li}
70*e47783fdSXin Li
71*e47783fdSXin Lifunc createCOptions(options *Options) C.struct_CZopfliPNGOptions {
72*e47783fdSXin Li	var cOptions C.struct_CZopfliPNGOptions
73*e47783fdSXin Li	C.CZopfliPNGSetDefaults(&cOptions)
74*e47783fdSXin Li	cOptions.lossy_transparent = boolToInt(options.LossyTransparent)
75*e47783fdSXin Li	cOptions.lossy_8bit = boolToInt(options.Lossy8bit)
76*e47783fdSXin Li	cOptions.num_iterations = C.int(options.NumIterations)
77*e47783fdSXin Li	cOptions.num_iterations_large = C.int(options.NumIterationsLarge)
78*e47783fdSXin Li	return cOptions
79*e47783fdSXin Li}
80*e47783fdSXin Li
81*e47783fdSXin Lifunc boolToInt(b bool) C.int {
82*e47783fdSXin Li	if b {
83*e47783fdSXin Li		return C.int(1)
84*e47783fdSXin Li	}
85*e47783fdSXin Li	return C.int(0)
86*e47783fdSXin Li}
87