Здравствуйте, Зверёк Харьковский, Вы писали:
ЗХ>В меру идиотский вопрос. ЗХ>Возможен ли сабж? Т.е. возможно ли создать переменную типа FILE*, чтобы все fwrite в нее на самом деле писали в буфер в памяти?
ЗХ>нужен JEPG в памяти; а libjpeg, зараза, либо через FILE*, либо какой-то кошмарный геморрой.
Да, возможно.
sprintf/sscanf именно так и делают.
Правда, вряд ли это кроссплатформенное решение — в разных системах поля FILE могут различаться.
csharper wrote:
> ЗХ>В меру идиотский вопрос. > ЗХ>Возможен ли сабж? Т.е. возможно ли создать переменную типа FILE*, чтобы все fwrite в нее на самом деле писали в буфер в памяти? > > ЗХ>нужен JEPG в памяти; а libjpeg, зараза, либо через FILE*, либо какой-то кошмарный геморрой. > > А если подсунуть ему хэндл на сокет или тому подобное что может работать с WriteFile?
Да, единственное, что в голову приходит fdopen() — открыть дескриптор pipe/socketpair/socket.
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.
...
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);
Здравствуйте, Зверёк Харьковский, Вы писали:
ЗХ>В меру идиотский вопрос. ЗХ>Возможен ли сабж? Т.е. возможно ли создать переменную типа FILE*, чтобы все fwrite в нее на самом деле писали в буфер в памяти?
ЗХ>нужен JEPG в памяти; а libjpeg, зараза, либо через FILE*, либо какой-то кошмарный геморрой.
А если подсунуть ему хэндл на сокет или тому подобное что может работать с WriteFile?
Здравствуйте, ivan_k, Вы писали:
_>Подтверждаю. Временные файлы — это очень быстро. Надо только правильно создавать
Мало, того, в условиях свопа, работа с памятью может сколько угодно тормозить )
Так что можно расслабиться по поводу того, что это всё разные якобы storages, а просто писал бы так, чтобы не вынуждать систему сливать файлы на диск
Скажем, если создавать файл r\w, потом писать туда всё что хочется, потом, не закрывая, отступать на начало, потом считывать куда надо, потом сбрасывать длину на ноль, то это всё будет довольно производительно в любой современной системе.
Мало того, скорее всего это всё хорошо закэшируется, даже если случайно какое-то из изображений выйдет неожиданно большим
С уважением, Егор.
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
В меру идиотский вопрос.
Возможен ли сабж? Т.е. возможно ли создать переменную типа FILE*, чтобы все fwrite в нее на самом деле писали в буфер в памяти?
нужен JEPG в памяти; а libjpeg, зараза, либо через FILE*, либо какой-то кошмарный геморрой.
Здравствуйте, csharper, Вы писали:
ЗХ>>В меру идиотский вопрос. ЗХ>>Возможен ли сабж? Т.е. возможно ли создать переменную типа FILE*, чтобы все fwrite в нее на самом деле писали в буфер в памяти?
ЗХ>>нужен JEPG в памяти; а libjpeg, зараза, либо через FILE*, либо какой-то кошмарный геморрой.
C>А если подсунуть ему хэндл на сокет или тому подобное что может работать с WriteFile?
Можно конечно попробовать, но так хотелось без грязных хаков...
Здравствуйте, 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++.
Здравствуйте, Зверёк Харьковский, Вы писали:
ЗХ>В меру идиотский вопрос. ЗХ>Возможен ли сабж? Т.е. возможно ли создать переменную типа FILE*, чтобы все fwrite в нее на самом деле писали в буфер в памяти?
ЗХ>нужен JEPG в памяти; а libjpeg, зараза, либо через FILE*, либо какой-то кошмарный геморрой.
А через временные файлы если попробовать? Пусть libjpeg туда запишет, что нужно. А ты затем заберешь.
... << RSDN@Home 1.1.4 beta 4 rev. 303>>
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Здравствуйте, Кодт, Вы писали:
К>Да, извини, что подсунул код для чтения из, а не записи в. К>Тебе же писать нужно...
Да ну, главное — идея. Оч. спасибо!
К>Кстати, вот. setvbuf()
Так а в этом случае, сдается мне, он будет сбрасывать этот буфер в файл — и с контролем над этим процессом видимо, будет туговато
Здравствуйте, Кодт, Вы писали:
К>Да, извини, что подсунул код для чтения из, а не записи в. К>Тебе же писать нужно... К>Кстати, вот. 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++.
Здравствуйте, eao197, Вы писали:
ЗХ>>В меру идиотский вопрос. ЗХ>>Возможен ли сабж? Т.е. возможно ли создать переменную типа FILE*, чтобы все fwrite в нее на самом деле писали в буфер в памяти?
ЗХ>>нужен JEPG в памяти; а libjpeg, зараза, либо через FILE*, либо какой-то кошмарный геморрой.
E>А через временные файлы если попробовать? Пусть libjpeg туда запишет, что нужно. А ты затем заберешь.
Так я и сам умею
Просто надо создать и вывести на экран около сотни небольших изображений, и самое тонкое место там (по скорости) — именно создание jpeg-а из готовой матрицы точек.
Здравствуйте, Зверёк Харьковский, Вы писали:
ЗХ>Здравствуйте, eao197, Вы писали:
ЗХ>>>В меру идиотский вопрос. ЗХ>>>Возможен ли сабж? Т.е. возможно ли создать переменную типа FILE*, чтобы все fwrite в нее на самом деле писали в буфер в памяти?
ЗХ>>>нужен JEPG в памяти; а libjpeg, зараза, либо через FILE*, либо какой-то кошмарный геморрой.
E>>А через временные файлы если попробовать? Пусть libjpeg туда запишет, что нужно. А ты затем заберешь.
ЗХ>Так я и сам умею ЗХ>Просто надо создать и вывести на экран около сотни небольших изображений, и самое тонкое место там (по скорости) — именно создание jpeg-а из готовой матрицы точек.
Ты знаешь, если изображения небольшие и создаются последовательно, и если для их формирования использовать один временный файл (который не закрывается и не флушируется), то скорость работы будет очень и очень приличной. Поскольку дисковые операции в современных файловых системах сильно и успешно кэшируются.
... << RSDN@Home 1.1.4 beta 4 rev. 303>>
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
eao197 wrote:
> ME>Да, единственное, что в голову приходит fdopen() — открыть дескриптор pipe/socketpair/socket. > > Вероятно под Windows это не прокатит.
По-моему, там можно обернуть HANDLE в FILE*. Винды нет под рукой чтоб проверить...
Здравствуйте, Зверёк Харьковский, Вы писали:
ЗХ>Возможен ли сабж? Т.е. возможно ли создать переменную типа FILE*, чтобы все fwrite в нее на самом деле писали в буфер в памяти?
ЗХ>нужен JEPG в памяти; а libjpeg, зараза, либо через FILE*, либо какой-то кошмарный геморрой.
Глянь на либу libpdel, там были разные реализации FILE*: с фильтрацией, с ограничением по размеру, в том числе и для чтения/записи буфера в памяти.
Здравствуйте, Patalog, Вы писали:
P>Здравствуйте, eao197, Вы писали:
P>[]
E>>Вероятно под Windows это не прокатит.
P>Почему не прокатит? Под виндой есть _pipe. И, как правильно заметил Максим, есть еще и _open_osfhandle.
Не знал, что под Windows есть _pipe. Спасибо.
... << RSDN@Home 1.1.4 beta 4 rev. 303>>
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
в продолжении вопроса... Т.е. у меня схожая задача, но мне нужно получить дескриптор на stream
Т.е. _fileno(...) и далее этот дискриптор пустить в оборот. В данном случае дескриптор не определен. как быть?
Здравствуйте, loknalori, Вы писали:
L>в продолжении вопроса... Т.е. у меня схожая задача, но мне нужно получить дескриптор на stream L>Т.е. _fileno(...) и далее этот дискриптор пустить в оборот. В данном случае дескриптор не определен. как быть?
Во-первых, ты можешь открыть pipe ( _popen() ). Пусть zlib туда пишет, а в другом потоке будешь читать и переписывать куда хочешь.
Во-вторых, посмотреть на исходники zlib и руками вписывать префикс gzip (10 байтов).
Оба способа умеренно-плохие.