>.
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | CFLAGS=-c -Wall -O0
2 |
3 | all: icopack
4 |
5 | icopack: main.o
6 | $(CC) main.o -o icopack
7 |
8 | main.o: main.c
9 | $(CC) $(CFLAGS) main.c
10 |
11 | clean:
12 | rm -rf main.o icopack
13 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | 
2 |
3 |
4 | Optidash is a modern, AI-powered image optimization and processing API.
We will drastically speed-up your websites and save you money on bandwidth and storage.
5 |
6 |
7 | ---
8 |
9 | A command line tool to create multi-frame ICO files from PNG source images.
10 |
11 |
12 |
13 |
14 | ---
15 |
16 | ### Intro
17 | This tool simply creates a valid ICO header and "glues" together the PNG files provided. Any other types of images will be rejected. `icopack` is the most efficient way to create Favicons.
18 |
19 | ### Background
20 | The ICO file format allows either uncompressed or PNG compressed images. The PNG images are stored as-is inside the file and accessed through a simple file header plus frame index. The PNG files can be palette or full color, but must be no larger than 256x256.
21 |
22 | ### Building
23 | ```bash
24 | $ make
25 | ```
26 |
27 | ### Usage
28 | ```bash
29 | $ icopack output.ico icon-1.png icon-2.png icon-N.png
30 | ```
31 |
32 | ### License
33 | This software is distributed under the GNU General Public License, Version 3. See the [LICENSE](LICENSE) file for more information.
--------------------------------------------------------------------------------
/main.c:
--------------------------------------------------------------------------------
1 | //
2 | // icopack - pack multiple PNG images into an ICO file
3 | //
4 | // Copyright (c) 2021 Optidash GmbH
5 | //
6 | // Licensed under the GNU General Public License, Version 3 (the "License");
7 | // you may not use this file except in compliance with the License.
8 | //
9 | // You may obtain a copy of the License at
10 | // https://www.gnu.org/licenses/gpl-3.0.en.html
11 | //
12 | // Unless required by applicable law or agreed to in writing, software
13 | // distributed under the License is distributed on an "AS IS" BASIS,
14 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | // See the License for the specific language governing permissions and
16 | // limitations under the License.
17 |
18 | #include
19 | #include
20 | #include
21 | #include
22 |
23 | int get_png_info(unsigned char *pIn, int iSize, int *width, int *height, int *bpp)
24 | {
25 | int w, h, i, j, bits=0;
26 | if (pIn[0] != 0x89 || pIn[1] != 0x50 || pIn[2] != 0x4e || pIn[3] != 0x47) {
27 | // PNG signature not present - not a PNG file
28 | return 1;
29 | }
30 | // Parse enough of the PNG file to get to the image header (IHDR) to get
31 | // the image size and bit depth
32 | w = (pIn[16] << 24) | (pIn[17] << 16) | (pIn[18] << 8) | pIn[19];
33 | h = (pIn[20] << 24) | (pIn[21] << 16) | (pIn[22] << 8) | pIn[23];
34 | i = pIn[24]; // bits per pixel
35 | j = pIn[25]; // pixel type
36 | switch (j) {
37 | case 0: // grayscale
38 | case 3: // palette image
39 | bits = i;
40 | break;
41 | case 2: // RGB triple
42 | bits = i * 3;
43 | break;
44 | case 4: // grayscale + alpha channel
45 | bits = i * 2;
46 | break;
47 | case 6: // RGB + alpha
48 | bits = i * 4;
49 | break;
50 | }
51 | *width = w; *height = h; *bpp = bits;
52 | return 0;
53 | } /* get_png_info() */
54 | //
55 | // Main program entry point
56 | //
57 | int main(int argc, char *argv[])
58 | {
59 | int i, j, iSize, iFileCount;
60 | int width, height, bpp;
61 | int iOffset;
62 | FILE *ihandle, *ohandle;
63 | unsigned char *pIn;
64 | unsigned char ucTemp[512];
65 |
66 | if (argc < 3 || argc > 16)
67 | {
68 | printf("icopack Copyright (c) 2021 Optidash GmbH\n");
69 | printf("Combines multiple PNG images into a single ICO file\n");
70 | printf("Source images must be <= 256 pixels in each dimension\n\n");
71 | printf("Usage: icopack \n");
72 | printf("example:\n\n");
73 | printf("icopack out.ico favicon1.png favicon2.png favicon3.png\n");
74 | return 0; // no filenames passed
75 | }
76 | iFileCount = argc - 2;
77 | ohandle = fopen(argv[1], "w+b");
78 | if (ohandle == NULL) {
79 | fprintf(stderr, "Unable to open output file: %s\n", argv[1]);
80 | return -1; // bad filename passed
81 | }
82 | // write an empty header; we'll fill it in later
83 | fwrite(ucTemp, 1, 6 + (iFileCount * 16), ohandle);
84 | ucTemp[0] = 0; // ICONDIR structure starts with 0,0
85 | ucTemp[1] = 0;
86 | ucTemp[2] = 1; // ICON file (2 = cursor file)
87 | ucTemp[3] = 0; // 2-byte int
88 | ucTemp[4] = (unsigned char)iFileCount;
89 | ucTemp[5] = 0; // 2-byte int
90 | iOffset = 6 + (iFileCount * 16); // starting offset of first file data
91 | for (i=2; i 256 || height > 256) {
112 | fprintf(stderr, "image files cannot be larger than 256x256; exiting...\n");
113 | return -1; // bad filename passed
114 | }
115 | // Fill in ICONDIRENTRY for this image
116 | j = 6 + (i-2) * 16;
117 | ucTemp[j] = (unsigned char)width;
118 | ucTemp[j+1] = (unsigned char)height;
119 | if (bpp < 8)
120 | ucTemp[j+2] = (1 << bpp); // number of colors
121 | else if (bpp == 8)
122 | ucTemp[j+2] = 255;
123 | else
124 | ucTemp[j+2] = 0; // non-palette image
125 | ucTemp[j+3] = 0; // reserved
126 | ucTemp[j+4] = 1; // color planes
127 | ucTemp[j+5] = 0; // 2-byte int
128 | ucTemp[j+6] = bpp;
129 | ucTemp[j+7] = 0; // 2-byte int
130 | *(uint32_t *)&ucTemp[j+8] = iSize; // image file size
131 | *(uint32_t *)&ucTemp[j+12] = iOffset; // offset to this image
132 | iOffset += iSize;
133 | // Write this image to the output file
134 | fwrite(pIn, 1, iSize, ohandle);
135 | free(pIn);
136 | fclose(ihandle);
137 | }
138 | // Seek to the beginning and update the ICONDIR and ICONDIRENTRY structures
139 | fseek(ohandle, 0, SEEK_SET);
140 | fwrite(ucTemp, 1, 6 + (iFileCount * 16), ohandle);
141 | fclose(ohandle);
142 | return 0;
143 | } /* main() */
144 |
--------------------------------------------------------------------------------
/media/logotype.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/optidash-ai/icopack/5b0144daf818f835fd990ffaccd3a6a251a6a454/media/logotype.png
--------------------------------------------------------------------------------