LINUX.ORG.RU

Си hex to file

 , ,


0

1

Извините, жестко туплую, как покороче буфер наполнить нужными хекс символами? а то мой код ниже как то криво выглядит

еще бы в 4-5 байты записать длину time(NULL)+2байта и после само это значение

uint8_t * buf = malloc(1024 * sizeof(uint8_t));

buf[0] = strtol("FF", NULL, 16);
buf[1] = strtol("D8", NULL, 16);
buf[2] = strtol("FF", NULL, 16);
buf[3] = strtol("FE", NULL, 16);
buf[4] = strtol("00", NULL, 16);
buf[5] = strtol("04", NULL, 16);

buf[10] = '\0';

FILE * pf = fopen("./test.jpg", "wb");
fwrite(buf, 1, 11, pf);
fclose(pf);

free(buf);

★★★

Последнее исправление: xaizek (всего исправлений: 1)

Ответ на: комментарий от sigurd

xaizek

спасибо разбираюсь

sigurd

думал собрать строку и ее потом в цикле прогнать, используя вместо NULL указатель

uint8_t *buf[]

не, у меня же маллок делается

wolverin ★★★
() автор топика
Последнее исправление: wolverin (всего исправлений: 1)
Ответ на: комментарий от xaizek

xaizek

обдумываю… по идее должно в буфере быть что то вроде

ffd8 fffe 000a 62BA D7E4

а не

ffd8 fffe 000a 0000 0000 62

wolverin ★★★
() автор топика
Последнее исправление: wolverin (всего исправлений: 6)
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>

int main(int argc, char *argv[])
{
    uint8_t patсh[] = 
    {
      0xff,0xd8,0xff,0xfe,0x00,0x04,
      0x00,0x00,0x00,0x00,0x00,0x00,
    };

    FILE * file = fopen("./test.jpg", "wb");
    fwrite(patсh, 1, sizeof(patсh), file);
    fclose(file); 

    return 0;
}
dron@gnu:~$ cat test.jpg | xxd -g 1
00000000: ff d8 ff fe 00 04 00 00 00 00 00 00              ............
dron@gnu:~$ 

еще бы в 4-5 байты записать длину time(NULL)+2байта и после само это значение

сформулируй нормально, тут понять можно раза 4 по разному

LINUX-ORG-RU ★★★★★
()
Ответ на: комментарий от LINUX-ORG-RU

LINUX-ORG-RU

)) как известно в вопросе обычно половина ответа, которая не была мне тоже известна

суть вопроса - надо в jpeg файл добавить комментарий после ffd8 с меткой времени, она добавляется следующим образом

fffe - начало комментария

00xx - размер комментария + 2 байта

хххххх - метка времени

вроде получилось, спасибо, я еще похоже лишнее обрезал перед записью в файл.

wolverin ★★★
() автор топика
Последнее исправление: wolverin (всего исправлений: 3)
Ответ на: комментарий от wolverin

А, ну для удобства ты бы мог в структуру описать, занести её в данные и просто записать её в файл. Но, если всё получилось и так то хорошо, значит нечего уже мудрить и городить иное.

LINUX-ORG-RU ★★★★★
()
Ответ на: комментарий от wolverin

тип такого, писал прям тут чисто как пример, само сообщение message не включено в запись.

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


int main(int argc, char *argv[])
{


    const uint16_t start = 0xfeff;
    char  comment[] = "hello";

    struct message
    {
        uint16_t comment_start_label;
        uint16_t comment_size;
        uint32_t comment_time;
    };

    /*+1 это учёт символа '\0' +2 это ты сказал*/
    struct message msg = {start, strlen(comment) + 1 + 2, (uint32_t)time(NULL)};

    FILE * file = fopen("./test.jpg", "wb");
    fwrite(&msg, 1, sizeof(struct message), file);
    fclose(file); 


    return 0;
}

я еще похоже лишнее обрезал перед записью в файл.

Я понятия не имею что там в заголовке джипега, но по хорошему надо весь заголовок так читать, менять и записывать обратно.

Или если в заголовке есть уже эти поля для комментария и место под него, то использовать fseek() смещаешься на нужный байт , кастуешь в нужный тип, пишешь туда, смещаешься дальше куда надо и так далее.

Если просто взять и дописать в файл то что мы записываем по идее ничего работать не будет

LINUX-ORG-RU ★★★★★
()
Последнее исправление: LINUX-ORG-RU (всего исправлений: 2)
Ответ на: комментарий от LINUX-ORG-RU

забыл, структуру надо бы обернуть так

#pragma pack(push, 1)
struct message
    {
        uint16_t comment_start_label;
        uint16_t comment_size;
        uint32_t comment_time;
    };
#pragma pack(pop)

Это нужно, когда мы структуры передаём по сети или в файл пишем, в общем во всех случаях когда мы работаем со структурой как с куском данных. Так она занимает ровно столько сколько занимают типы внутри неё. Без выранивания с «дырами» в обычном случае когда мы работаем со структурой в рамках просто использования в коде.

LINUX-ORG-RU ★★★★★
()
Последнее исправление: LINUX-ORG-RU (всего исправлений: 1)
Ответ на: комментарий от LINUX-ORG-RU

LINUX-ORG-RU

СПАСИБО!!!!

немного переделал Ваш пример

struct jpg_note
{
    uint8_t head[4];
    uint16_t size;
    uint32_t tt;
};

int main(int argc, char * argv[])
{

    uint32_t tt = time(NULL);

    printf("%u\n", tt);
    struct jpg_note jpg = {{0xff,0xd8,0xff,0xfe}, sizeof(tt), tt};

    FILE * pf = fopen("./test.jpg", "wb");
    fwrite(&jpg, 1, sizeof(jpg), pf);
    fclose(pf);

НО теперь получаю байты в обратном порядке (

1656427446

00000000: ffd8 fffe 0400 0000 b613 bb62 ………..b

похоже без сдвига никак просто не обойтись

wolverin ★★★
() автор топика
Последнее исправление: wolverin (всего исправлений: 1)
Ответ на: комментарий от wolverin

Порядок байт поменяй https://ru.stackoverflow.com/questions/600774/%D0%98%D0%BD%D0%B2%D0%B5%D1%80%D1%82%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D1%82%D1%8C-%D0%BF%D0%BE%D1%80%D1%8F%D0%B4%D0%BE%D0%BA-%D0%B1%D0%B0%D0%B9%D1%82

будет struct jpg_note jpg = {{0xff,0xd8,0xff,0xfe}, reverse_16( sizeof(tt)), reverse_32(tt)};

Можно превтратить структуру в массив байт

struct jpg_note jpg = {{0xff,0xd8,0xff,0xfe}, sizeof(tt), tt};

char * data = (char)&jpg;
//теперь верти крути этой data как обычным char массивом, например поменять местами 5й и 6й байты

char save = data[6];
data[6] = data[7];
data[7] = save;
/*можно и без save но так понятнее*/

fwrite записывает как есть, вот и.

Есть ещё станлартная сетевая функция/ции для смены порядка байт, но я забыл как там оно =)

про #pragma pack не забудь, (выше я писал) а то появятся нулевые байты из неоткуда и запутаешься.

LINUX-ORG-RU ★★★★★
()
Последнее исправление: LINUX-ORG-RU (всего исправлений: 2)
Ответ на: комментарий от wolverin

Нет не пойдёт, тогда запишется адрес на буфер, а не буфер. Если надо что-то не линейное. То проще последовательно записывать всё опция за опцией. Короче можно много как ибо Си, выше пример как кастовать структуру в массив, можно просто выделить массив нужного размера под всё, кастовать к нужному типу и записывать значения, потом просто массив записать в файл. Это решение в лоб, но оно часто (мне) удобнее так как всё получается пусть и длинно, но прото как топор. например

char * data = (char*)malloc(sizeof(uint32_t) + sizeof(uint64_t) + sizeof(uint8_t));

uint32_t * data32 = (uint32_t*)data;
*data32 = 65535;

uint64_t * data64 = (uint64_t*)(data+sizeof(uint32_t));
*data64 = 646841654;

uint8_t * data8 = (uint8_t*)(data+sizeof(uint32_t)+sizeof(uint64_t));
*data8 = 'Q';

//теперь в массиве data лежат три числа разного типа
//конечно можно писать гораздо короче, но я размазал так вроде понятнее что куда
//писал тут прям может где ошибся, но принцип думаю понятен

Но сам заголовок у тебя статичный, так что структурой пойдёт, а само сообщение никто не мешает записать после записи заголовка.

Чёт типа такого как то так :D

LINUX-ORG-RU ★★★★★
()
Последнее исправление: LINUX-ORG-RU (всего исправлений: 2)
Ответ на: комментарий от LINUX-ORG-RU

кастовать структуру в массив

А ничо, что выравнивание членов структуры (если не их взаимное расположение — лень лезть в стандарт) вообще-то implementation defined? Но ты кастуй, кастуй, лол.

(Потом такие вот ноют, что им GC в сях не хватает. А из-за дефицита кадров и к критическим системам пролезают ведь уже…)

alegz ★★★★
()
Ответ на: комментарий от alegz

implementation defined

уговорили ) вернусь к массиву и буду его сбрасывать в файл

    uint32_t tt = time(NULL);

    printf("%u\n", tt);

    uint8_t jpg_note[10] = {0xff,0xd8,0xff,0xfe,0,0x06};
    for (unsigned int i = 0; i < 4; ++i)
        jpg_note[6 + i] = tt >> (8*(4 - 1 - i));

    FILE * pf = fopen("./test.jpg", "wb");
    fwrite(jpg_note, 1, sizeof(jpg_note), pf);
    fclose(pf);
wolverin ★★★
() автор топика
Ответ на: комментарий от alegz

А ничо, что выравнивание членов структуры (если не их взаимное расположение — лень лезть в стандарт) вообще-то implementation defined?

Выравнивание. Поэтому он и говорит, про обязательное #pragma pack или __attribute__((packed)). Такое себе, но, если архитектура не требует обязательного выравнивания (вроде SPARC, если не ошибаюсь), то должно работать.

SkyMaverick ★★★★★
()
Ответ на: комментарий от wolverin

лично я бы сделал гораздо проще (зачем копировать в промежуточный буфер) -

uint8_t jpg_note[10] = {0xff,0xd8,0xff,0xfe,0,0x06};
for (unsigned int i = 0; i < 4; ++i)
    jpg_note[6 + i] = tt >> (8*(4 - 1 - i));

fwrite(jpg_note, 1, sizeof(jpg_note), pf);

заменил на

uint8_t jpg_note[6] = {0xff,0xd8,0xff,0xfe,0,0x06};
fwrite(jpg_note, 1, sizeof(jpg_note), pf);
fwrite(&tt, sizeof(tt), 1, pf);
sigurd ★★★★★
()
Последнее исправление: sigurd (всего исправлений: 2)