Groovy hepcat
gi************* *@yahoo.it was jivin' on 17 Mar 2006
08:18:58 -0800 in comp.lang.c.
Re: Raw image in header file's a cool scene! Dig it!
Sorry I would like to take a raw image file and convert it to an header
file, generating an array that contains in each cell the gray level
that corresponds to the pixel.
It will be useful in order to avoid read from hd that on my target
platform (an embedded system) can become very slow.
Hope this is not ot.
Such things don't belong in headers. They belong in the main part of
a translation unit (ie., the .c file). Headers should contain external
declarations of functions and variables, macro definitions and such.
But, to your question, how do you store an image (or other) file in
a C source file? It's really quite easy, believe it or not. All you
have to do is read each byte of the file and use its value as an
initialiser for an array. "Tedious, time consuming and error prone," I
hear you say? Au contraire. It's extremely easy and efficient, if you
let the computer do it. Now I hear you ask, "But how do I do that?"
You use a simple utility that reads a file and outputs C source code
containing an array initialised with the contents of the file. Your
next question: "Where do I get a utility like that?"
You write one. Yes, that's right. You write your own utility. It's
really quite trivial. But if you feel that such a beastie is beyond
your skills at this time, you can use the following program, which I
wrote and have used. I call it c-embed. (I realise someone already
posted a program like this, but it was untested and not as good. If
you want something that has at least been tried out, use my program.)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define NELEMENTS_PER_L INE 10
void instruct(void)
{
const char *const helptext =
"c-embed\n\n"
"Use:\n"
"c-embed <output_prefi x> <file_1> [<file_2> [<file_3>"
" [...<file_n>]]] > <output_file>\n \n"
"c-embed takes one or more filenames on the command line,\n"
"reads in those files, converts them to C (or C++) arrays\n"
"then outputs each array to <output_prefix> .c and puts extern\n"
"declaratio ns of these arrays in <output_prefix> .h, thus enabling"
" you\n"
"to embed files within programs written in C (or C++) as"
" arrays.\n"
"<output_prefix > may be a dash, in which case arrays will be"
" output\n"
"to standard output and no header will be created.\n"
"The arrays will be called embed_N, where N is the number of"
" the\n"
"file. For example, the first file will be embedded as embed_1,"
" the\n"
"second as embed_2, the third as embed_3, etc.\n";
fputs(helptext, stderr);
}
int main(int argc, char **argv)
{
size_t i;
FILE *cfp, *hfp;
char cfn[FILENAME_MAX + 1];
char hfn[FILENAME_MAX + 1];
if(3 > argc)
{
instruct();
return EXIT_FAILURE;
}
if(0 != strcmp("-", argv[1]))
{
sprintf(cfn, "%s.c", argv[1]);
cfp = fopen(cfn, "w");
if(!cfp)
{
fprintf(stderr, "Error opening file \"%s\"\n", argv[1]);
return EXIT_FAILURE;
}
sprintf(hfn, "%s.h", argv[1]);
hfp = fopen(hfn, "w");
if(!hfp)
{
fprintf(stderr, "Error opening file \"%s\"\n", argv[1]);
fclose(cfp);
return EXIT_FAILURE;
}
}
else
{
cfp = stdout;
hfp = NULL;
}
for(i = 2; i < argc; i++)
{
FILE *ifp;
ifp = fopen(argv[i], "rb");
if(!ifp)
{
fprintf(stderr, "Error opening file \"%s\"\n", argv[i]);
if(hfp)
{
fclose(hfp);
}
fclose(cfp);
return EXIT_FAILURE;
}
else
{
size_t j, n;
int ch;
fprintf(cfp, "/* embed_%lu contains file \"%s\". */\n",
(unsigned long)i - 1, argv[i]);
fprintf(cfp, "const unsigned char embed_%lu[] =\n{",
(unsigned long)i - 1);
for(j = 0, n = 0; EOF != (ch = fgetc(ifp)); j++, n++)
{
if(0 == (j % NELEMENTS_PER_L INE))
{
j = 0;
fputc('\n', cfp);
fputc('\t', cfp);
}
else
{
fputc(' ', cfp);
}
fprintf(cfp, "0x%2.2x,", (unsigned)ch);
}
fputs("\n};\n\n ", cfp);
if(hfp)
{
fprintf(hfp, "/* embed_%lu contains file \"%s\". */\n",
(unsigned long)i - 1, argv[i]);
fprintf(hfp, "extern const unsigned char embed_%lu[%lu];\n\n",
(unsigned long)i - 1, (unsigned long)n);
}
}
fclose(ifp);
}
fclose(cfp);
if(hfp)
{
fclose(hfp);
}
return 0;
}
Using this program is quite simple. Suppose you want to embed a file
named image.jpg in a C file named image.c. You do this:
c-embed image image.jpg
This creates image.c and puts an array of const unsigned char called
embed_1 in it, initialised with the contents of image.jpg. It also
creates image.h, and puts an extern declaration of the array in there.
You can embed any file this way, even multiple files.
--
Dig the even newer still, yet more improved, sig!
http://alphalink.com.au/~phaywood/
"Ain't I'm a dog?" - Ronny Self, Ain't I'm a Dog, written by G. Sherry & W. Walker.
I know it's not "technicall y correct" English; but since when was rock & roll "technicall y correct"?