1 // Copyright (C) 2021 Harry Godden (hgn) - All Rights Reserved
6 #define STB_IMAGE_IMPLEMENTATION
7 #include "stb/stb_image.h"
16 int image_sort( const void* a
, const void* b
)
18 struct image_src
*p_a
= (struct image_src
*)a
;
19 struct image_src
*p_b
= (struct image_src
*)b
;
21 if( p_a
->x
== p_b
->x
)
23 else if ( p_a
->x
< p_b
->x
)
29 int main( int argc
, const char *argv
[] )
31 struct image_src
*source_images
= malloc( sizeof( struct image_src
) * argc
);
37 vg_error( "Missing output file paths\n" );
43 FILE *fp
= fopen( argv
[2], "w" );
46 vg_error( "Could not open file for writing\n" );
50 fprintf( fp
, "static enum %s_index\n{\n", argv
[3] );
54 stbi_set_flip_vertically_on_load(1);
56 for( int i
= 4; i
< argc
; i
++ )
58 struct image_src
*src
= &source_images
[ num_images
];
59 src
->data
= (u8
*)stbi_load( argv
[i
], &src
->x
, &src
->y
, &src
->ch
, 4 );
62 int j
= 0; int ext
= 0;
63 for( ; j
< vg_list_size( name
)-1; j
++ )
72 if( name
[j
] == '.' || name
[j
] == '-' )
84 fprintf( fp
, "\tk_sprite_%s,\n", name
);
88 if( src
->x
!= src
->y
)
90 vg_error( "Non-square images are currently not supported ('%s')\n", argv
[i
] );
97 vg_error( "Could not decode '%s'\n", argv
[i
] );
100 fprintf( fp
, "};\n\n" );
104 qsort( source_images
, num_images
, sizeof(struct image_src
), image_sort
);
108 fprintf( fp
, "static struct vg_sprite %s[] = \n{\n", argv
[3] );
110 u8
*dest
= (u8
*)malloc( 1024*1024*4 );
113 for( int i
= 0; i
< 1024*1024; i
++ )
117 dest
[ i
*4 + 2 ] = 128;
118 dest
[ i
*4 + 3 ] = 255;
137 for( int i
= 0; i
< num_images
; i
++ )
139 struct image_src
*psrc
= &source_images
[ i
];
144 struct region
*pregion
= ®ion_stack
[ stack_h
];
146 if( (pregion
->p0
[ 0 ] + psrc
->x
<= pregion
->p1
[0]) && (pregion
->p0
[ 1 ] + psrc
->y
<= pregion
->p1
[1]) )
148 // Passed, add image and create subdivisions
149 fprintf( fp
, "\t{ %hu, %hu, %hu, %hu },\n",
150 (u16
)(sf
* pregion
->p0
[0]),
151 (u16
)(sf
* pregion
->p0
[1]),
157 for( int y
= 0; y
< psrc
->y
; y
++ )
159 int px
= pregion
->p0
[0];
160 int py
= pregion
->p0
[1] + y
;
162 memcpy( &dest
[ (py
*1024+px
) * 4 ], &psrc
->data
[ y
*psrc
->x
*4 ], psrc
->x
*4 );
167 struct region
*new_region
= ®ion_stack
[ stack_h
];
169 new_region
->p0
[0] = pregion
->p0
[0] + psrc
->x
;
170 new_region
->p0
[1] = pregion
->p0
[1];
171 new_region
->p1
[0] = pregion
->p1
[0];
172 new_region
->p1
[1] = pregion
->p0
[1] + psrc
->y
;
174 pregion
->p0
[ 1 ] += psrc
->y
;
179 // Failed, loop up to next region if can
182 vg_error( "Could not fit image %d. Pack failed\n", i
);
198 qoi_write( argv
[1], dest
, &(qoi_desc
){
202 .colorspace
= QOI_SRGB
207 for( int i
= 0; i
< num_images
; i
++ )
208 free( source_images
[ i
].data
);
210 free( source_images
);
212 vg_success( "Processed %u images\n", num_images
);