FILE* в памяти
От: Зверёк Харьковский  
Дата: 06.04.05 13:04
Оценка:
В меру идиотский вопрос.
Возможен ли сабж? Т.е. возможно ли создать переменную типа FILE*, чтобы все fwrite в нее на самом деле писали в буфер в памяти?

нужен JEPG в памяти; а libjpeg, зараза, либо через FILE*, либо какой-то кошмарный геморрой.
это мы, Зверьки!
FAQ — це мiй ай-кью!
Re: FILE* в памяти
От: csharper  
Дата: 06.04.05 13:12
Оценка: +1
Здравствуйте, Зверёк Харьковский, Вы писали:

ЗХ>В меру идиотский вопрос.

ЗХ>Возможен ли сабж? Т.е. возможно ли создать переменную типа FILE*, чтобы все fwrite в нее на самом деле писали в буфер в памяти?

ЗХ>нужен JEPG в памяти; а libjpeg, зараза, либо через FILE*, либо какой-то кошмарный геморрой.


А если подсунуть ему хэндл на сокет или тому подобное что может работать с WriteFile?
Re[2]: FILE* в памяти
От: MaximE Великобритания  
Дата: 06.04.05 13:16
Оценка: 39 (2) +1
csharper wrote:

> ЗХ>В меру идиотский вопрос.

> ЗХ>Возможен ли сабж? Т.е. возможно ли создать переменную типа FILE*, чтобы все fwrite в нее на самом деле писали в буфер в памяти?
>
> ЗХ>нужен JEPG в памяти; а libjpeg, зараза, либо через FILE*, либо какой-то кошмарный геморрой.
>
> А если подсунуть ему хэндл на сокет или тому подобное что может работать с WriteFile?

Да, единственное, что в голову приходит fdopen() — открыть дескриптор pipe/socketpair/socket.

--
Maxim Yegorushkin
Posted via RSDN NNTP Server 1.9
Re[2]: FILE* в памяти
От: Зверёк Харьковский  
Дата: 06.04.05 13:18
Оценка:
Здравствуйте, csharper, Вы писали:

ЗХ>>В меру идиотский вопрос.

ЗХ>>Возможен ли сабж? Т.е. возможно ли создать переменную типа FILE*, чтобы все fwrite в нее на самом деле писали в буфер в памяти?

ЗХ>>нужен JEPG в памяти; а libjpeg, зараза, либо через FILE*, либо какой-то кошмарный геморрой.


C>А если подсунуть ему хэндл на сокет или тому подобное что может работать с WriteFile?


Можно конечно попробовать, но так хотелось без грязных хаков...
это мы, Зверьки!
FAQ — це мiй ай-кью!
FILE* в памяти
От: Кодт Россия  
Дата: 06.04.05 13:18
Оценка: 156 (17)
#Имя: FAQ.cpp.fileinmemory
Здравствуйте, Зверёк Харьковский, Вы писали:

ЗХ>В меру идиотский вопрос.

ЗХ>Возможен ли сабж? Т.е. возможно ли создать переменную типа FILE*, чтобы все fwrite в нее на самом деле писали в буфер в памяти?

ЗХ>нужен JEPG в памяти; а libjpeg, зараза, либо через FILE*, либо какой-то кошмарный геморрой.


Да, возможно.
sprintf/sscanf именно так и делают.
Правда, вряд ли это кроссплатформенное решение — в разных системах поля FILE могут различаться.
void* yourdata;
int yoursize;

FILE file;
// VC6, подсмотрено в sscanf.c
file._flag = _IOREAD|_IOSTRG|_IOMYBUF;
file._ptr = file._base = (char *) yourdata;
file._cnt = yoursize;

FILE* fp = &file;
Перекуём баги на фичи!
Re[2]: FILE* в памяти
От: Кодт Россия  
Дата: 06.04.05 13:36
Оценка:
Да, извини, что подсунул код для чтения из, а не записи в.
Тебе же писать нужно...
Кстати, вот. setvbuf()
Перекуём баги на фичи!
Re[3]: FILE* в памяти
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 06.04.05 13:38
Оценка:
Здравствуйте, MaximE, Вы писали:

ME>csharper wrote:


>> ЗХ>В меру идиотский вопрос.

>> ЗХ>Возможен ли сабж? Т.е. возможно ли создать переменную типа FILE*, чтобы все fwrite в нее на самом деле писали в буфер в памяти?
>>
>> ЗХ>нужен JEPG в памяти; а libjpeg, зараза, либо через FILE*, либо какой-то кошмарный геморрой.
>>
>> А если подсунуть ему хэндл на сокет или тому подобное что может работать с WriteFile?

ME>Да, единственное, что в голову приходит fdopen() — открыть дескриптор pipe/socketpair/socket.


Вероятно под Windows это не прокатит.
... << RSDN@Home 1.1.4 beta 4 rev. 303>>


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re: FILE* в памяти
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 06.04.05 13:48
Оценка:
Здравствуйте, Зверёк Харьковский, Вы писали:

ЗХ>В меру идиотский вопрос.

ЗХ>Возможен ли сабж? Т.е. возможно ли создать переменную типа FILE*, чтобы все fwrite в нее на самом деле писали в буфер в памяти?

ЗХ>нужен JEPG в памяти; а libjpeg, зараза, либо через FILE*, либо какой-то кошмарный геморрой.


А через временные файлы если попробовать? Пусть libjpeg туда запишет, что нужно. А ты затем заберешь.
... << RSDN@Home 1.1.4 beta 4 rev. 303>>


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[3]: FILE* в памяти
От: Зверёк Харьковский  
Дата: 06.04.05 13:50
Оценка:
Здравствуйте, Кодт, Вы писали:

К>Да, извини, что подсунул код для чтения из, а не записи в.

К>Тебе же писать нужно...
Да ну, главное — идея. Оч. спасибо!

К>Кстати, вот. setvbuf()


Так а в этом случае, сдается мне, он будет сбрасывать этот буфер в файл — и с контролем над этим процессом видимо, будет туговато
это мы, Зверьки!
FAQ — це мiй ай-кью!
Re[3]: FILE* в памяти
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 06.04.05 13:51
Оценка:
Здравствуйте, Кодт, Вы писали:

К>Да, извини, что подсунул код для чтения из, а не записи в.

К>Тебе же писать нужно...
К>Кстати, вот. setvbuf()

Я так понял, что ты предлагаешь установить свой буфер, затем, не вызывая fflush() и fclose() забрать его содержимое?

Но что произойдет, если закрыть файл? Ведь, как я понял, сначала нужно открыть какой-то временный файл, получить FILE *. Затем заменить у него буфер. Обратиться к libjpeg. Затем забрать данные из буфера. Но ведь файл-то закрыть придется.

Можно перед закрытием еще раз сменить буфер, но вот, что по этому поводу говорят здесь:

The setvbuf() function may be used at any time, but may have peculiar
side effects (such as discarding input or flushing output) if the stream
is ``active''. Portable applications should call it only once on any
given stream, and before any I/O is performed.

... << RSDN@Home 1.1.4 beta 4 rev. 303>>


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[2]: FILE* в памяти
От: Зверёк Харьковский  
Дата: 06.04.05 13:52
Оценка:
Здравствуйте, eao197, Вы писали:

ЗХ>>В меру идиотский вопрос.

ЗХ>>Возможен ли сабж? Т.е. возможно ли создать переменную типа FILE*, чтобы все fwrite в нее на самом деле писали в буфер в памяти?

ЗХ>>нужен JEPG в памяти; а libjpeg, зараза, либо через FILE*, либо какой-то кошмарный геморрой.


E>А через временные файлы если попробовать? Пусть libjpeg туда запишет, что нужно. А ты затем заберешь.


Так я и сам умею
Просто надо создать и вывести на экран около сотни небольших изображений, и самое тонкое место там (по скорости) — именно создание jpeg-а из готовой матрицы точек.
это мы, Зверьки!
FAQ — це мiй ай-кью!
Re[3]: FILE* в памяти
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 06.04.05 14:01
Оценка:
Здравствуйте, Зверёк Харьковский, Вы писали:

ЗХ>Здравствуйте, eao197, Вы писали:


ЗХ>>>В меру идиотский вопрос.

ЗХ>>>Возможен ли сабж? Т.е. возможно ли создать переменную типа FILE*, чтобы все fwrite в нее на самом деле писали в буфер в памяти?

ЗХ>>>нужен JEPG в памяти; а libjpeg, зараза, либо через FILE*, либо какой-то кошмарный геморрой.


E>>А через временные файлы если попробовать? Пусть libjpeg туда запишет, что нужно. А ты затем заберешь.


ЗХ>Так я и сам умею

ЗХ>Просто надо создать и вывести на экран около сотни небольших изображений, и самое тонкое место там (по скорости) — именно создание jpeg-а из готовой матрицы точек.

Ты знаешь, если изображения небольшие и создаются последовательно, и если для их формирования использовать один временный файл (который не закрывается и не флушируется), то скорость работы будет очень и очень приличной. Поскольку дисковые операции в современных файловых системах сильно и успешно кэшируются.
... << RSDN@Home 1.1.4 beta 4 rev. 303>>


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[4]: FILE* в памяти
От: MaximE Великобритания  
Дата: 06.04.05 14:17
Оценка:
eao197 wrote:

> ME>Да, единственное, что в голову приходит fdopen() — открыть дескриптор pipe/socketpair/socket.

>
> Вероятно под Windows это не прокатит.

По-моему, там можно обернуть HANDLE в FILE*. Винды нет под рукой чтоб проверить...

--
Maxim Yegorushkin
Posted via RSDN NNTP Server 1.9
Re[4]: FILE* в памяти
От: ivan_k Россия  
Дата: 06.04.05 15:18
Оценка: 1 (1) +1
Здравствуйте, eao197, Вы писали:


E>Ты знаешь, если изображения небольшие и создаются последовательно, и если для их формирования использовать один временный файл (который не закрывается и не флушируется), то скорость работы будет очень и очень приличной. Поскольку дисковые операции в современных файловых системах сильно и успешно кэшируются.


Подтверждаю. Временные файлы — это очень быстро. Надо только правильно создавать


CreateFile
...
FILE_ATTRIBUTE_TEMPORARY
The file is being used for temporary storage. File systems avoid writing data back to mass storage if sufficient cache memory is available, because often the application deletes the temporary file shortly after the handle is closed. In that case, the system can entirely avoid writing the data. Otherwise, the data will be written after the handle is closed.
...

Re: FILE* в памяти
От: Elifant  
Дата: 07.04.05 02:12
Оценка:
Здравствуйте, Зверёк Харьковский, Вы писали:

ЗХ>Возможен ли сабж? Т.е. возможно ли создать переменную типа FILE*, чтобы все fwrite в нее на самом деле писали в буфер в памяти?


ЗХ>нужен JEPG в памяти; а libjpeg, зараза, либо через FILE*, либо какой-то кошмарный геморрой.


Глянь на либу libpdel, там были разные реализации FILE*: с фильтрацией, с ограничением по размеру, в том числе и для чтения/записи буфера в памяти.
Re[5]: память, файлы -- какая разница? :)
От: Erop Россия  
Дата: 07.04.05 06:32
Оценка: +1
Здравствуйте, ivan_k, Вы писали:

_>Подтверждаю. Временные файлы — это очень быстро. Надо только правильно создавать


Мало, того, в условиях свопа, работа с памятью может сколько угодно тормозить )

Так что можно расслабиться по поводу того, что это всё разные якобы storages, а просто писал бы так, чтобы не вынуждать систему сливать файлы на диск

Скажем, если создавать файл r\w, потом писать туда всё что хочется, потом, не закрывая, отступать на начало, потом считывать куда надо, потом сбрасывать длину на ноль, то это всё будет довольно производительно в любой современной системе.
Мало того, скорее всего это всё хорошо закэшируется, даже если случайно какое-то из изображений выйдет неожиданно большим

С уважением, Егор.
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re: FILE* в памяти
От: DarkOn Латвия  
Дата: 08.04.05 12:27
Оценка: +2
Здравствуйте, Зверёк Харьковский, Вы писали:

ЗХ>нужен JEPG в памяти; а libjpeg, зараза, либо через FILE*, либо какой-то кошмарный геморрой.


Ну незнаю где там кошмарный геморой, там все просто. Например так:

typedef struct jmemdst_s
{
    struct jpeg_destination_mgr dst;
    byte *data;
    size_t asize;        // allocated size
    size_t isize;        // image size
} jmemdst_t;

static void init_destination(j_compress_ptr cinfo)
{
    jmemdst_t *dst=(jmemdst_t *)cinfo->dest;

    dst->isize=0;
    dst->dst.free_in_buffer=dst->asize-dst->isize;
    dst->dst.next_output_byte=dst->data+dst->isize;
}

static boolean empty_output_buffer(j_compress_ptr cinfo)
{
    jmemdst_t *dst=(jmemdst_t *)cinfo->dest;

// write current buffer
    dst->isize=dst->asize;
    dst->asize+=64*1024;    // 64Kb increments
    dst->data=realloc(dst->data, dst->asize);

    dst->dst.free_in_buffer=dst->asize-dst->isize;
    dst->dst.next_output_byte=dst->data+dst->isize;
    return TRUE;
}

static void term_destination(j_compress_ptr cinfo)
{
    jmemdst_t *dst=(jmemdst_t *)cinfo->dest;

// compression complete
    dst->isize=dst->asize-dst->dst.free_in_buffer;
}

static void jpeg_mem_dst(j_compress_ptr cinfo)
{
    jmemdst_t *dst;

// allocate destination manager object
    dst=(jmemdst_t *)(*cinfo->mem->alloc_small)((j_common_ptr)cinfo, JPOOL_PERMANENT, sizeof(jmemdst_t));
// allocate memory
    dst->isize=0;
    dst->asize=64*1024;    // 64Kb initial image size
    dst->data=malloc(dst->asize);

// initialize
    dst->dst.free_in_buffer=dst->asize-dst->isize;
    dst->dst.next_output_byte=dst->data+dst->isize;
    dst->dst.init_destination=init_destination;
    dst->dst.empty_output_buffer=empty_output_buffer;
    dst->dst.term_destination=term_destination;

// assign
    cinfo->dest=(struct jpeg_destination_mgr*)dst;
}


использование:

unsigned char *data;
size_t isize;

<...>

    jpeg_create_compress(&cinfo);
//    jpeg_stdio_dest(&cinfo, fp);
    jpeg_mem_dst(&cinfo);

<....>

// get data & size, don't forget to free data
    data=((jmemdst_t *)cinfo.dest)->data;
    isize=((jmemdst_t *)cinfo.dest)->isize;

// release compression object
    jpeg_destroy_compress(&cinfo);

// тут имеем данные в data[] и размер в isize

<....>

// не забываем освободить память
    free(data);


удачи!
... << RSDN@Home 1.1.4 beta 4 rev. 303>>
--
keep on coding..
Re[4]: FILE* в памяти
От: Patalog Россия  
Дата: 08.04.05 13:14
Оценка: 15 (2)
Здравствуйте, eao197, Вы писали:

[]

E>Вероятно под Windows это не прокатит.


Почему не прокатит? Под виндой есть _pipe. И, как правильно заметил Максим, есть еще и _open_osfhandle.
Почетный кавалер ордена Совка.
Re[5]: FILE* в памяти
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 08.04.05 13:19
Оценка:
Здравствуйте, Patalog, Вы писали:

P>Здравствуйте, eao197, Вы писали:


P>[]


E>>Вероятно под Windows это не прокатит.


P>Почему не прокатит? Под виндой есть _pipe. И, как правильно заметил Максим, есть еще и _open_osfhandle.


Не знал, что под Windows есть _pipe. Спасибо.
... << RSDN@Home 1.1.4 beta 4 rev. 303>>


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re: FILE* в памяти
От: c-smile Канада http://terrainformatica.com
Дата: 08.04.05 19:14
Оценка:
Здравствуйте, Зверёк Харьковский, Вы писали:

Как я понимаю тебе это надо для показать картинку в HTMLayout?

Если да, то там есть такой сервис:


#define SAVE_IMAGE_AS_PNG   0x1
#define SAVE_IMAGE_AS_JPEG  0x2

struct HTMLAYOUT_HDIB_SAVE_API
{
  virtual HERESULT __stdcall saveHdibToFile(HBITMAP hDib, DWORD type, LPCSTR path)
  virtual HERESULT __stdcall saveHdibToMemory(HBITMAP hDib, DWORD type, LPBYTE dataptr, LPDWORD datasize)
};


struct HTMLAYOUT_HDIB_API
{
  virtual HERESULT __stdcall loadHdibFromFile(LPCSTR path, HDIBEX* pOutHDib) = 0;
  virtual HERESULT __stdcall loadHdibFromMemory(LPCBYTE dataptr, DWORD datasize, HDIBEX* pOutHDib) = 0;
  virtual HERESULT __stdcall destroyHdib(HDIBEX hdib) = 0;
  virtual HERESULT __stdcall getHdibInfo(HDIBEX hdib, LPBITMAPINFO pBbitmapInfo) = 0;
  virtual HERESULT __stdcall getHdibBits(HDIBEX hdib,LPBYTE *ppBytes, LPDWORD pNumOfBytes) = 0;
  virtual HERESULT __stdcall renderHdib(HDC dstDC, int dstX, int dstY, int dstWidth, int dstHeight, HDIBEX hdib) = 0;
  virtual HERESULT __stdcall renderHdib(HDC dstDC, int dstX, int dstY, int dstWidth, int dstHeight, int srcX, int srcY, HDIBEX hdib) = 0;
  virtual HERESULT __stdcall renderHdib(HDC dstDC, int dstX, int dstY, int dstWidth, int dstHeight, int srcX, int srcY, int srcWidth, int srcHeight, HDIBEX hdib) = 0;
} HTMENGINE_HDIB_API;


Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.