0

I'm trying to read a JPG image file and convert it to string of hex code (not hex of pixel) in C.

Something like:

FFD8FFE000114A464946000102030405060708090AFFDB00....

I tried many way but not working. Someone has any idea?

My code which I tried with stb libraries: https://codeload.github.com/nothings/stb/zip/master

// USAGE: gcc -std=c99 image.c -o image -lm
#include <stdio.h>
#include <math.h>
#define STB_IMAGE_IMPLEMENTATION
#include "stb_image.h"

const size_t NUM_PIXELS_TO_PRINT = 10U;

int main(void) {
    int width, height, comp;
    unsigned char *data = stbi_load("r3.jpg", &width, &height, &comp, 0);
    if (data) {
        printf("width = %d, height = %d, comp = %d (channels)\n", width, height, comp);
        for (size_t i = 0; i < NUM_PIXELS_TO_PRINT * comp; i++) {
            printf("%02x%s", data[i], ((i + 1) % comp) ? "" : "\n");
        }
        printf("\n");
    }
    return 0;
}

The error I got when try with John Smith:

ImageProcess.c: In function ‘main’:
ImageProcess.c:14:5: warning: implicit declaration of function ‘bzero’ [-Wimplicit-function-declaration]
     bzero(data, fsize + 1);
     ^
ImageProcess.c:18:5: warning: implicit declaration of function ‘hexlifyn’ [-Wimplicit-function-declaration]
     char* yourDataStr = hexlifyn((char*)data, (uint)fsize);
     ^
ImageProcess.c:18:48: error: ‘uint’ undeclared (first use in this function)
     char* yourDataStr = hexlifyn((char*)data, (uint)fsize);
                                                ^
ImageProcess.c:18:48: note: each undeclared identifier is reported only once for each function it appears in
ImageProcess.c:18:53: error: expected ‘)’ before ‘fsize’
     char* yourDataStr = hexlifyn((char*)data, (uint)fsize);
                                                     ^
ImageProcess.c: At top level:
ImageProcess.c:21:28: error: unknown type name ‘uint’
 char *hexlifyn(char *bstr, uint str_len) {
                            ^
ToanVnET
  • 105
  • 4
  • 14
  • 3
    Can you elaborate what you actually want the hex string to represent? Should it just be a binary dump of the file (i.e. represent "the bytes on the harddrive")? – Joel Bodenmann Mar 31 '20 at 10:25
  • Actually, I don't know much about what hex can be represented on image. But the bytes on the hardware seem like quite compatible with my case. – ToanVnET Mar 31 '20 at 10:41
  • I tried with stb libraries but it only get hex of each pixel. – ToanVnET Mar 31 '20 at 10:45
  • 2
    It is not clear what you want. If you don't want hex of each pixel, do you mean, you do not want to decompress the JPG file? Do you just want to read the file and write content (compressed JPG) as hex string? – Gerhardh Mar 31 '20 at 10:48
  • Yes, Gerhardh. I want to write content as hex string. – ToanVnET Mar 31 '20 at 11:31
  • 1
    _"I tried with stb libraries but it only get hex of each pixel"_: show us what you have tried, then me might be able to tell you what you id wrong. [Edit] your question and clarify. Read this: [ask] – Jabberwocky Mar 31 '20 at 11:37
  • Yes, you have been updated my question. – ToanVnET Mar 31 '20 at 11:57
  • 1
    It's still unclear what you want. What makes you think your code is not working? Does your code compile? Does it run? Does it crash? Does it display something else than what you expect? Please [edit] and clarify. "Not working" is not a problem description. – Jabberwocky Mar 31 '20 at 12:03
  • No, my code is working, but I get hex of pixel. – ToanVnET Mar 31 '20 at 12:04
  • 1
    @ToanVnET so you basically want to read the jpg file byte per byte and display the hexadecimal representation to each of the bytes? Please confirm. – Jabberwocky Mar 31 '20 at 12:10
  • Yes, Jabberwocky. – ToanVnET Mar 31 '20 at 12:12
  • 2
    You don't need STB_image at all, because you aren't trying to understand or interpret or process the image in any way at all... all you are doing is a hex dump, same as you'd get if you ran `xxd -p IMAGE.JPG` and `xxd` knows nothing about JPEG/PNG or anything else. You just need to open your file in binary and read each byte and display it in hex. – Mark Setchell Mar 31 '20 at 14:13
  • How can I reach that ? It's sound great. – ToanVnET Apr 01 '20 at 01:05
  • 1
    Thank you so much Mark Setchell. I solved my issue. Same way as you said. – ToanVnET Apr 01 '20 at 13:20

3 Answers3

3

If your goal is to get the contents of a file as hex string than that should work:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void main() { 
    char* file_name = "/path/to/any.png";
    FILE *f = fopen(file_name, "rb");
    if (f==NULL) return;
    fseek(f, 0, SEEK_END);
    size_t fsize = ftell(f);
    fseek(f, 0, SEEK_SET);

    void*data = malloc(fsize + 1);
    bzero(data, fsize + 1);
    fread(data, 1, fsize, f);
    fclose(f);

    char* yourDataStr = hexlifyn((char*)data, (uint)fsize);
}

char *hexlifyn(char *bstr, uint str_len) {
    char *hstr=malloc((str_len*2)+1);
    bzero(hstr,(str_len*2)+1);
    char *phstr=hstr;
    for(int i=0; i<str_len;i++) {
        *phstr++ =v2a((bstr[i]>>4)&0x0F);
        *phstr++ =v2a((bstr[i])&0x0F);
    }
    *phstr++ ='\0';
    return hstr;
}

char v2a(int c) {
    const char hex[] = "0123456789abcdef";
    return hex[c];
}
John Smith
  • 573
  • 6
  • 22
  • No. It's not working. A lot of warning and error. Did I missing something when I compiled it: `gcc -std=c99 ImageDumpHex.c -o image` – ToanVnET Apr 01 '20 at 01:04
  • It seems you don‘t have much knowledge of C in many regards, so I would advice you to read online about the basics at least. If you absolutely need to fix it now, for the uint error, it’s defined here `#include `, for the warnings, you need to write a header for the functions of course or move them above the caller (main) – John Smith Apr 01 '20 at 11:25
  • Thank you, I solved my issues. I just open file image and read each byte of image and display it. – ToanVnET Apr 01 '20 at 13:17
  • @JohnSmith how to get it back to its original format? – Yeezus Nov 09 '21 at 20:07
1

From your comment I understand that you want to retrieve the binary contents of a file (i.e. a JPG image) as a hexadecimal string.

What you're looking for is something called "hex dump". There are various libraries and snippets available that allow doing this with C.

This stackoverflow question addresses exactly this issue.

Joel Bodenmann
  • 2,152
  • 2
  • 17
  • 44
  • I work in C. I not sure these C++ function is working with C. – ToanVnET Mar 31 '20 at 11:33
  • 2
    The crucial part of this answer is the fact that you're looking for doing a "hex dump". That information should open you a door of a multitude of ready-to-go solutions from small copy-paste code snippets up to fully fledged library integrated solutions. To point you to something specific we'd need to know more about your requirements. – Joel Bodenmann Mar 31 '20 at 11:35
0

This will give you image file output as a continuous hex string in your terminal as well as a .txt file:

#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <fstream>

using namespace std;
string myText;
int main()
{
  system("xxd -p image.jpg > image.txt | tr -d '\n'");
  

ifstream MyReadFile("./image.txt");

while (getline (MyReadFile, myText)) {
  // Output the text from the file
  cout << myText;
}


MyReadFile.close(); 
  return 0;
}