ImageProcessing-ElectronicPublications / scantailor-experimental

Scan Tailor Experimental is an interactive post-processing tool for scanned pages.
https://github.com/Tulon/scantailor/tree/experimental
GNU General Public License v3.0
30 stars 0 forks source link

TIFF и Mixed Raster Content mode #32

Open plzombie opened 2 months ago

plzombie commented 2 months ago

В RFC 2301 написано, что TIFF может содержать три слоя

The 3 layers of the MRC model are Foreground and Background, which are both multi-level, and Mask, which is bi-level. Each layer may appear only once on a page and is coded independently of the other two. In our earlier example, the black-and-white text could be in the Mask layer, the color chart in the Foreground layer, and the color image in the Background layer.

Насколько я понимаю, Scantailor сейчас не поддерживает такой режим. Изображение созраняется как фон (без маски). Вроде как Scantailor Featured мог сохранять две копии изображения - bg и отдельно mask.

Собственно, предложение. Для смешанного режима реализовать сохранение в mixed raster context. А потом уже разбираться, как сконвертировать это в djvu.

@zvezdochiot @noobie-iv @trufanov-nok (вроде никого не забыл) - нет возражений?

trufanov-nok commented 2 months ago

Емнип STU, STA и наверное что-то им предшествовавшее, реализуют экспорт слоев страницы на этапе output. В отдельные файлы. Экспортируются в т.ч. background и foreground. Маска на этом этапе в этом режиме хранится неявно - у оригинального изображения пиксели 0x000000 И 0xFFFFFF (или только 0x000000 - не помню) резервируются под слой foreground (текст), везде где не picture zone. Т.о. экспорт представляет собой переписывания одного файла в два на основании pixel_color == 0x000000. Эти слои в дальнейшем собираются в djvu по методу раздельных сканов при помощи DjVu Imager. Он понимает только слои в виде отдельных файлов.
Смысла кодировать что-то в MRC я особого не вижу. Кодировщиков в djvu из tiff с его поддержкой нет. Насколько вьюверы его поддерживают, особенно в tiff - не ясно. Вот в wiki про Tiff ни слова: https://en.wikipedia.org/wiki/Mixed_raster_content
В STU кстати есть вроде экспорт слоев в multilayer или multipage tiff - не помню. Но это не совсем MRC. Но? кол-во файлов можно сэкономить.
Остается вопрос сохранения цветовой схемы (резервирование 0x000000 в не отмеченных picture зонами областей в mixed mode за текстовым слоем можно избегать)... Но это очень древняя фича и ее изменение потребует усилий.

В общем, ничего кроме лишнего геморроя...

noobie-iv commented 2 months ago

Я использую в основном STA для перевода документов по работе в PDF. В документах дела обстоят так:

  1. Есть текст и черно-белые чертежи. Их надо переводить в монохром 600dpi
  2. Есть малоцветные чертежи, графики и т.п. Их надо переводить в малоцветную палитру 600dpi, 4-8 цветов. Возможно, принудительно, указывая эти несколько цветов мышкой.
  3. Есть многоцветные чертежи. Полноцвет слишком тяжел, а малоцвет их портит. Обычно там палитры от 64 до 256 цветов. Разрешение - спорный вопрос, иногда 600dpi, а иногда можно оставлять 300dpi, они не улучшаются от увеличения.
  4. Есть фото. Их вообще трогать не надо, они от этого только портятся. Разрешение надо оставлять как было, а обрезать в идеале хотелось бы как делает BetterJPEG, обратно в jpeg без перекодирований.
  5. Иногда все эти варианты встречаются прямо на одной странице.

Мне нужно, чтобы страница содержала несколько изображений разного формата и разрешения одновременно, обрабатывала каждый из них по-своему, и экспорт нужен в разные форматы сразу. Эта идея вообще никак не совместима с той реализацией, что есть сейчас в любой из версий ST. Тут не то что tiff поправить, тут саму систему хранения и обработки изображений переделывать надо - идентификаторы, кеши, устройство фильтров и видов. Из-за этого я и завел STD, но, похоже, не вывезу; по крайней мере, пока знания по плюсам не подтяну.

zvezdochiot commented 2 months ago

@noobie-iv , тогда смотри в сторону pnmtodjvurle. DjVuRLE позволяеет делать SEP-файлы (foreground+background), которые кодируются в djvu непосредственно утилитами csepdjvu или msepdjvu.

PS:

По поводу разделённых сканов. Я пользую CropperTktoPDF. Но хотелось бы иметь поделку на Qt и без reportlab для генерации PDF, ибо он использует кодировку ASCII85.

По поводу JPEG, использую комбинацию Info из Crop в PhotoQuick с шагом 16 + jpegtran + jpeg2pdf с полями (-m) по информации из PhotoQuick. (хотелось бы конечно иметь гуишный инструмент).

Для комбинации отдельх "слоёв" (PDF) в страницу имеется qpdf.

trufanov-nok commented 2 months ago

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

А вы можете это сделать в каком-нибудь Photoshop, GIMP или SkanKromsator? Если да - то...

Есть пословица паскудная: "лучшее - враг хорошего". ST меня когда-то купил своей простотой. Я лет 8 назад его запустил, два раза куда-то тыкнул - и получил отличный (как мне тогда казалось) результат. Мне какие-то фичи были нужны (преимущественно хоткеи) - я их докрутил. Остальные спрятал в настройки, чтобы сохранить простой UX. До сих пор использую. Потом выяснилось существование метода раздельных сканов и это единственное, к.м.к., недочет ST семейства - что они не форсят создание djvu по этому методу, имея при том полуавтоматический сегментатор слоев внутри.

Какие-то попытки изменить первоначальный концепт - например, этапы обработки местами менять - приводят к серьёзным пропихиванием невпихуемого в разные места кода, куда оно идти не должно. Это - возможно, смогут это "не только лишь все" и мало кому это уже надо, но и удивляться что оно идет против шерсти концепта - бессмысленно.

plzombie commented 2 months ago

@trufanov-nok

Емнип STU, STA и наверное что-то им предшествовавшее, реализуют экспорт слоев страницы на этапе output. В отдельные файлы. Экспортируются в т.ч. background и foreground. Маска на этом этапе в этом режиме хранится неявно - у оригинального изображения пиксели 0x000000 И 0xFFFFFF (или только 0x000000 - не помню) резервируются под слой foreground (текст), везде где не picture zone. Т.о. экспорт представляет собой переписывания одного файла в два на основании pixel_color == 0x000000. Эти слои в дальнейшем собираются в djvu по методу раздельных сканов при помощи DjVu Imager. Он понимает только слои в виде отдельных файлов.

Видимо оно там тоже было когда-то. Потому что создаётся background слой с маской 0x000000 и 0xFFFFFF прямо на нём. Но как мне в StEx сделать отдельно background+отдельно foreground, а желательно ещё и отдельно маску, я не нашёл.

@zvezdochiot

По поводу разделённых сканов. Я пользую CropperTktoPDF. Но хотелось бы иметь поделку на Qt и без reportlab для генерации PDF, ибо он использует кодировку ASCII85.

Ну вот оно уже есть в StEx. Осталось сохранить в тот же tiff (благо в теории формат позволяет даже разбить фон на несколько изображений)

Я не думаю, что это прамо архисложно, написать утилиту, которая будет конвертировать tiff+MRC в pdf или djvu. Всё равно, данной функциональности сейчас нет вообще

plzombie commented 2 months ago

На майских потыкаю палкой и StEx, и tiff. Если удастся сделать без ущерба к существующему функционалу и реализации, попробую добавить

noobie-iv commented 2 months ago

У нас в строительстве официяльные документы принимают в PDF, потому я DJVU не использую, не у всех на него смотрелки есть. А для быстрой сборки в PDF я свалял простейшую консольку, которая папку OUT после STA разом пакует: https://forum.dwg.ru/showthread.php?t=167830. С этим уже жить можно, я так под тыщщу гостов собрал.

Текст у меня обрабатывает STA, а картинки в режиме разделения сканов я как раз в GIMP пережимаю, перед упаковкой в PDF. Деварп мне, собственно, не нужен - сканы обычно не кривые. И всего, чего не хватает - различать не два типа изображений на странице, как сейчас во всех ST, а три за раз, чтобы всю обработку в ST делать, а не ёрзать туда-сюда постоянно.

ST, конечно, простые, но у них ограничение - книги либо только с фото, либо только с малоцветками. А наши нормотворцы в новых документах взяли моду вместо ЧБ чертежей, как в старые добрые времена, вставлять что попало, даже фотки низкого разрешения из интернета, даже диаграммы желтым по белому, и прочую ересь. Вот с ними ST и не справляется в автомате. Нужен ST, у которого автомат малость посложнее. И потому же я в отдельную программу ушел, а не в реквесты на исходные STA/STU.

zvezdochiot commented 2 months ago

@plzombie , @noobie-iv , етить вашу мать, дайте ссылку на этот ваш StEx!

PS: @noobie-iv , пользовать MRC в PDF категорически не рекомендую. В PDF есть родной, простой и понятный способ илюстрирования - кадрирование изображений и наложение их сверху/снизу. А MRC в PDF - это сплошные и дикие тормоза во всех просмотрщиках + проблемы (!!!) с печатью.

plzombie commented 2 months ago

@zvezdochiot Я этот форк имею в виду

zvezdochiot commented 2 months ago

Кажется я начал понимать за что речь. Но ежели это действительно так, то я "улыбаюсь" с этой истории, ибо всё опять возвращается к макетированию страниц. И без макетирования вы желаемого результата не получите никак. Такие вот дела. ;)

zvezdochiot commented 2 months ago

@plzombie say:

На майских потыкаю палкой и StEx

Тогда посмотри ещё: 1) как бы в FillZones пристроить no-kmeans, чтобы убрать его из PictureZones? 2) как бы в Zones добавить для оконтуривания XSpline: #30?

plzombie commented 2 months ago

@zvezdochiot да там ещё и вылетает редко при переходе от зон картинок к зонам заливки. Надо это поотлаживать прежде чем что-либо делать. Но займусь

plzombie commented 2 months ago

@zvezdochiot К слову, можешь мне объяснить, что происходит, когда в смешанном режиме выбираешь цвет заливки? Такое ощущение, что за гранью "зоны картинок" он приводится к чб

zvezdochiot commented 2 months ago

@plzombie , да, я "химичил" с заливкой из-за k-means. И мне самому не до конца понятно, как грамотно организовать заливку. Надо ковыряться.

Вспомнил ещё один неприятный момент: в IntegralImage напрочь отсутствует метод принудительного высвобождения. Сейчас они висят до завершения области видимости. Да, некритично, ибо все процедуры короткие, но сам факт неприятный.

noobie-iv commented 2 months ago

@zvezdochiot say:

пользовать MRC в PDF категорически не рекомендую

А как без него, если STA экспортирует две страницы одного размера - ЧБ+ЦВЕТ. Вот и приходится просто считать ЧБ маской, и сводить с картикной как есть.

всё опять возвращается к макетированию страниц

Чтобы не было MRC, в этом макете надо сохранять не маску, а набор честных габаритных прямоугольников в пределах страницы. Такой макет совсем не похож на то, что есть сейчас - ссылка на исходное изображение, контур подрезки и поворот. И система хранения другая, и обработка страниц видами другая. А если еще позволить разные разрешения в пределах страницы - то и система хранения изображений другая.

Собственно, это я и имел ввиду, когда затевал STD. Ну, пока об нехватку знаний не споткнулся. Если починю там битые превьюшки, есть шанс, что и остальное доделаю (тогда уж и в STEX починить их смогу, и в STA). Но это еще очень нескоро будет.

zvezdochiot commented 2 months ago

@noobie-iv , неверно. Совсем.

Как раз с изображение делать что то "несусветное" вовсе нет надобности. Надобно либо сохранять отдельно xml макета, для использования его в дальнейшем, либо парсить сам проект STEX. В любом случае надобна дополнительная тулза для генерации PDF по макету из одного (ОДНОГО!) обычного tiff-а. Что то типа DjVu-Imager на новый лад. Такие вот дела. ;)

noobie-iv commented 2 months ago

парсить сам проект STEX

Я не сохраняю проекты. Я скачиваю очередной гост, пропускаю в автомате через STA, и пакую как есть. А после STEX разные части картинки еще и перепаковывать надо, каждую в свой формат, это долго и лень.

изображение делать что то "несусветное" вовсе нет надобности

У меня есть. Мне принципиально надо, чтобы любой фильтр мог прогнать изображение через любую внешнюю команду. Может, деварп сторонний. Может, GMIC. Может, даже в GIMP для ручной правки. А значит, у фильтра своя временная папка заводится под редактированные изображения, чтобы он их дальше передавал, а не оригинал с подправленной рамкой, как сейчас. Но это все в STD должно быть. STEX я не трогаю, пусть остается минималистичным. Да я и STD не трогаю, тупой я для этого, просветления жду 😄

zvezdochiot commented 2 months ago

@noobie-iv , опять таки имеет место быть согласие.

Ежели сделать отдельную прогу макетирования страницы, то это решило бы очень много вопросов. А ваши вопросы порешало бы полностью. Необходимость макетирования в STEX для сложных страниц не отпала бы, но конструкция STEX->{GIMP, Krita, ...}->QPageMaket->PDF очень даже логична.

plzombie commented 2 months ago

В tiff можно сохранять в передний/задний план отдельные области, а не всё изображение уменьшенное То есть останутся отдельно иллюстрации (отдельные слои типа заднего плана), один чб слой типа маски и опционально можно в передний план что-нибудь добавить (а можно не добавлять - просто весь передний план закрасить чёрным цветом)

plzombie commented 2 months ago

То есть дело за конвертером MRC TIFF => PDF. Ну и в STEX это добавить (собственно, для чего я этот топик создавал)

zvezdochiot commented 2 months ago

@plzombie say:

То есть дело за конвертером MRC TIFF => PDF.

Нифига. MRC в PDF - это тормозное говно, которое хрен нормально распечатаешь и вообще нафиг ненужно. Другое дело постоение страницы из отдельных блоков по макету.

noobie-iv commented 2 months ago

конвертером MRC TIFF => PDF

Чтобы такое было возможно и полезно, надо, чтобы в TIFF разные слои хранились с разным сжатием, для текста и картинок отдельно. Он так умеет? А лично мне надо, чтобы еще и на одной странице могли быть разные области с разным сжатием: монохром/fax4, фото/jpeg, малоцвет/lossless-palette, полноцвет/lossless.

В tiff можно сохранять в передний/задний план отдельные области

А их положение на странице он помнит? Например, как в редакторах, работающих со слоями, когда наложенную сверху заплатку можно подвигать туда-сюда? Если да, то из него можно будет честный PDF делать, без MRC. И еще хорошо бы, чтобы это чудо можно было просматривать, а не просто знать, что там внутри особая магия есть. Какой вьюер/редактор так может?

zvezdochiot commented 2 months ago

@noobie-iv , по вашим запросам, STEX должен генерить на выходе постраничные PDF, а значит как минимум уметь FAX CCITT GROUP4, либо JBIG2, FLATE, настраиваемый JPEG, либо JPEG2000. Но это не просто и сильно осложнит дальнейшую обработку. Такие вот дела. ;)

noobie-iv commented 2 months ago

По моим запросам надо еще в обработку добавить редактирование через внешние программы. Тогда экспортированный PDF вообще не надо дальнейше обрабатывать.

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

А если делать экспорт под дальнейшую обработку, все равно же придется вместе с картинками еще и контуры/координаты записывать (даже если считать, что они уже записаны в проекте). И такое просто посмотреть уже никто не может, надо конвертер/смотрелку дописывать. А зачем смотрелка, которая смотрит то, что в ST не доделано, и которая, кроме как за ST посмотреть, больше ничего не может? Такая смотрелка должна быть частью ST - это фильтр "Export" должен быть.

zvezdochiot commented 2 months ago

@noobie-iv say:

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

Так это ж S-кривая (сдвоенная дуга) в фильтрах. И стоит уже по дефолту на 0.5. Помимо этого есть C-кривая (чистая дуга).

noobie-iv commented 2 months ago

Мне начало и конец сдвигать надо, а не на месте оставлять. А сама кривая должна оставаться прямой, только повернутой вокруг центра. Такое еще яркость-контраст делают, но менее удобно. А S и C для другого, они тени и света сохранить пытаются, а их срезать надо, там только шум лишний. И кроме кривых, еще иногда палитру выборочную надо сделать. Или еще что-то оригинальное. Проще всего это во внешних программах делать. В идеале - через интерфейс ST. Но он от этого из "простой программы" превращается в комбайн. И с этим много кто несогласен будет.

А что еще важнее, в STEX нет разделения вывода, и даже если какой фильтр сработает, результат потом опять обрабатывать надо - картинки выделять, пережимать. Потому я STEX не использую вообще, в моих документах STA+самодельный PDF быстрее выходит, даже с промежуточной ручной обработкой картинок.

zvezdochiot commented 2 months ago

@noobie-iv say:

Но он от этого из "простой программы" превращается в комбайн. И с этим много кто несогласен будет.

Ну так это только ваша задумка. От того всё сложно и получается, потому как вы эту сложность заложить и пытаетесь. Моя же задумка - макетирование страниц и поблочная обработка, что оставляет простоту для простых страниц, но позволяет любую сложность для сложных страниц. И полностью согласуется со структурой STEX. Такие вот дела. ;)

PS: Я больше скажу: в моей задумке перенести вкладки зон с Output на Blocks, тем самым разгузив Output и упростив работу с Zones.

PS2: Я конечно могу занести в STEX: https://github.com/ImageProcessing-ElectronicPublications/imthreshold/blob/c03843f92b8c8644822d5c77eb06cfd587b0680b/src/filter.cpp#L33-L34 https://github.com/ImageProcessing-ElectronicPublications/imthreshold/blob/c03843f92b8c8644822d5c77eb06cfd587b0680b/src/filter.cpp#L42-L43 https://github.com/ImageProcessing-ElectronicPublications/imthreshold/blob/c03843f92b8c8644822d5c77eb06cfd587b0680b/src/filter.cpp#L47-L49 , но не жирновато ли будет по фильтрам? Длина списка увеличится почти в двое! И чего тогда с ним делать? Только ежели заменить список на подсписок главных фильтров (S-,C-кривые и выравнивание) и селектор вспомогательных. Но с ГУИ у меня траблы, так что не по мне выделка. Вот ежели на уже имеющихся фильтрах покажите, как это грамотно сделать, тогда я дополню список селектора вспомогательных фильтров.

PS3: Фильтр, о котором вы говорили - это собственно LevelMean в списке выше. ;)

noobie-iv commented 2 months ago

От того всё сложно и получается, потому как вы эту сложность заложить и пытаетесь.

Я еще ничего не добавил, а мне уже сложно. Вот сейчас в STD поломаны превьюшки. Не я их придумал, они там есть, и они битые. Чтобы выдать первый релиз, осталось их починить. Заодно превью глючат в STEX. И в STA в половине случаев запуск пакетной обработки обрывается на середине.

На новый год я пару дней просидел в отладчике, и вообще ничего не понял. У меня выписана трассировка щелчка мыши при выборе другого фильтра. Трассировка содержит только основные функции, ведущие к превьюшкам. Трассировка занимает под сотню строк вызовов, с уровнем вложенности под десяток. И несколько раз она прерывает сама себя, и внутри начинается заново с вызова очередной цепочки под десятый уровень вложенности. Это работают потоки, лазающие в кеш за картинками. И они в конце работы закидывают очередные задания в очередь на обработку. Иногда их перебивают какие-то фильтры событий главного окна. Иногда срабатывают какие-то сигналы, выброшенные непонятно кем. Может, это Qt сама себе сигналит, а может, ST сигналит. В любом случае при отладке иногда вместо перехода к следующей строке я попадаю в очередную цепочку вызовов, которая непонятно откуда прилетела, и непонятно где кончается.

Чтобы в этой каше разобраться, надо знать, как писать в Qt многопоток, с учетом сигналов и фильтров. Чтобы, например, глядя на какой-нибудь метод, понимать, что это на самом деле переопределение какого-то базового метода обратного вызова, и что его в любой момент может неявно вызвать кто-то другой. Или что его могут прервать. И кто там кого может прервать. И кто обязательно будет первым, а кто может завершиться позже. Или что вот этот метод - переопределение стандартного, который может кидаться сигналами. А чтобы разобраться, надо минимум разок написать с нуля что-то похожее. И это минимум несколько месяцев, при наличии кучи свободного времени.

Мини-проект "для разобраться" я себе завел. Сколько времени он отнимет - не знаю. С одной стороны, учить Qt мне нафиг не надо, потому что больше оно мне нигде не понадобится. С другой стороны, поразбираться с многопотоком, возможно, полезно. Так что какое-то время я еще здесь. Если после проекта починить STD до релизного состояния не выйдет, придется на участие в ST забить.

А до той поры нет никаких шансов, что я смогу добавить хоть что-то типа нового вида зон, дополнительной стадии и т.п. Вот поломать, как превьюшки в STD - это могу поучаствовать. Да беседу в комментариях поддержать завсегда пожалуйста.

zvezdochiot commented 2 months ago

@noobie-iv say:

учить Qt мне нафиг не надо, потому что больше оно мне нигде не понадобится.

Ну как. Ежели следовать логике коментария, то вполне может пригодиться, для ваяния QPageMaket без всяких там потоков, а по примитиву. Потому как нет особых вариантов, учитывая ваши запросы на пост-обработку в различных прогах.

zvezdochiot commented 2 months ago

@plzombie , @noobie-iv , пока не забыл, потрещите с Александром aka @trufanov-nok , нельзя ли как то на Output через итерратор minidjvu прикрутить в виде унификатора "символов". Вот это было бы очень полезной (в плане читабельности книги) фитчёй.

PS: Или хотя бы сделать этот унификатор отдельной тулзой, без сношений с JB2.

plzombie commented 2 months ago

@zvezdochiot @noobie-iv Пока разбираюсь, в очередной раз столкнулся с такой проблемой, как определить, где именно у меня упадёт код (на инициализации какого объекта?)

try {
  RAIIHandlerA i, j, k;
  RAIIHandlerB x,y, z;
} catch(ExceptionA ex_a) {
  std::cout << "Exception of Hande type A\n";
} catch(ExceptionB ex_b) {
  std::cout << "Exception of Handle type B\n";
}

В том же скантейлоре обрабатывается только один тип ошибок, std::bad_alloc. Причём, обработчик находится вокруг функции main, и функция "продолжить работу" там как бы и не предусмотрена.

Ну и это у меня тривиальный пример ещё. RAII же предполагает, что я все объекты должен в конструкторе инициализировать. Гуглил, но мне выдаёт только про невозможность кинуть ошибку из деструктора. А как отследить ошибку, которая была кинута в конструкторе, и не оборачивать в try {} catch {} всё содержимое main, никто, почему-то, не пишет

zvezdochiot commented 2 months ago

@plzombie , добавь флаг -g к опциям компиляции, запускай gdb ./you_program, понаставь breakout на свои конструкторы и запускай на выполнение от точки останова до точки останова. Как то так.

plzombie commented 2 months ago

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

trufanov-nok commented 2 months ago

Емнип, нельзя позволять exception выбрасываться за пределы конструктора, например вот поэтому: https://stackoverflow.com/a/71887635/841424 Если в конструкторе есть код, который может выдать excepion - его нужно в конструкторе и ловить, а потом коммуницировать об ошибке какимто др способом: флаг m_isValid ставить, Qt сигнал с описанием ошибки бросать...

plzombie commented 2 months ago

@trufanov-nok это всё прекрасно, но прямо любой пример по RAII берёшь, и там конструктор кидает exception. Моя бы воля, я бы в конструкторе вообще ничего не делал кроме инициализации атрибутов простых типов, а всё остальное в методы Create()/Destroy() (ну и в деструкторе if(isInit()) Destroy(); добавить)

noobie-iv commented 2 months ago

@plzombie

и не оборачивать в try {} catch {} всё содержимое main

В любой функции можно сгородить вложенный блок-трюкач. Есть даже специальный синтаксис, когда все тело функции - один большой блок:

#include <iostream>

void f() try {
    throw 0;
} catch (...) {
    std::cout << "Oops!";
}

int main()
{
    f(); // Oops!
}

Так же можно завернуть в блок все тело конструктора или деструктора, тогда из них тоже ничего не вылетит:

#include <iostream>

struct A { 
    A() { throw 0; }
};

struct B : public A
{
    B() try : A() {} catch(...) { std::cout << "Gotcha!"; }
};

int main()
{
    B b; // Gotcha!
}

любой пример по RAII берёшь, и там конструктор кидает exception

Если исключением кидается конструктор, все OK. Просто на уровне какой-то функции (не обязетельно main) надо сгородить трюкача, который разбирается с последствиями.

А если кидается деструктор - то один раз так сделать можно, все даже будет работать. Но вот если исключение уже выброшено, и еще не обработано до конца, прямо сейчас идет чистка стека, а чей-то деструктор кинет еще одно исключение - тогда программа вылетает без возможности обработки. Почему так - не пишут, видимо, есть сложности в реализации на уровне компилятора, про которые слишком долго рассказывать. Может, параллельная обработка ломает гарантию чистки в порядке, обратном созданию. Может, добавляет код, который должен работать и в случае, если исключение не выброшено. А может, еще какие фокусы есть.

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

я бы в конструкторе вообще ничего не делал кроме инициализации атрибутов простых типов

Еще пишут, что плюсовый код на исключениях работает быстрее, чем сишный на ручной обработке кодов возврата, потому что в основной логике программы нет никаких лишних ветвлений. Вроде как для того исключения и придумали - ускорить код, плюс никогда не забывать про обработку.

А вот если исключение вылетело - тут тормоза будут сильнее, чем при ручной обработке, поэтому нельзя включать трюкачей в основную логику взамен всяких if-then, и тем более в нагруженные циклы.

Вариант с ручной обработкой через Create/Destroy получается средним - вроде есть автоматическая чистка, но возвращается лишняя писанина с проверкой, которую можно забыть. И если забыть, то появляется объект, который вроде как создан, но внутри-то у него мусор. Из-за этого придется лепить чтото вроде if( ! IsInit() ) Create(); на каждом вызове каждого метода, на случай, что Create забыли сделать при создании. Подозреваю, что для решения этой проблемы придумали паттерн Builder, который весь этот геморрой прячет внутри метода Build - и ловит исключения, и выпускает наружу только правильно созданный объект, и потому позволяет внутри методов лишних проверок не ставить.

никто, почему-то, не пишет

Есть такая проблема, да. Я с плюсами на любительском уровне лет 15 знаком, а программистом не стал. Полно книг для чайников, но нет для кофейников. Я и в этот проект полез из любопытства - хоть раз посмотреть, как реальные программы устроены, а не примеры "сложите 2 и 2. подумайте, можно ли их еще и умножать".

zvezdochiot commented 2 months ago

@plzombie say:

Моя бы воля, я бы

Сделайте уже нормальный селектор доп.фильтров (к основным относятся только кривые и выравнивание). А то я сам от безысходности его слеплю и это будет откровенно кривая, уродливая и глючная фигня!

zvezdochiot commented 1 month ago

@zvezdochiot say:

А то я сам от безысходности его слеплю и это будет откровенно кривая, уродливая и глючная фигня!

Ну как то так: https://github.com/ImageProcessing-ElectronicPublications/scantailor-experimental/commit/51b8f42354306ba314370c57d15bead7636e0784

zvezdochiot commented 1 month ago

@noobie-iv say:

Мини-проект "для разобраться" я себе завел. Сколько времени он отнимет - не знаю. С одной стороны, учить Qt мне нафиг не надо, потому что больше оно мне нигде не понадобится. С другой стороны, поразбираться с многопотоком, возможно, полезно. Так что какое-то время я еще здесь. Если после проекта починить STD до релизного состояния не выйдет, придется на участие в ST забить.

Доп. матариал (значительно более простой для разбора): Yet Another Scan Wizard.

zvezdochiot commented 1 month ago

@plzombie , в релизе не перебор? ( :question: в названиях файлов и Win32, и X86-64).

PS: Ежели всё норм, то я в винде вообще перестаю что то понимать. Одним словом меня можно назвать - "ископаемое".

plzombie commented 1 month ago

@zvezdochiot Win32 - программная платформа, x86-64 - аппаратная. А то не совсем понятно, для чего конкретно данный зип архив

zvezdochiot commented 1 month ago

@plzombie , ну так "этого" я и не распарсиваю. Win32 - это 32-битная винда, а x86-64 - это 64-битная.

PS: применяют обозначения либо "win32" и "win64", либо "win-x86" и "win-x86-64", но никак не "win32-x86-64".

plzombie commented 1 month ago

PS: применяют обозначения либо "win32" и "win64", либо "win-x86" и "win-x86-64", но никак не "win32-x86-64".

Есть старое апи (называемое Win16), есть Win32, есть UWP Отдельного Win64 как такового нет https://learn.microsoft.com/ru-ru/windows/win32/ Если называть так 64бит версию, то не понятно, как тогда обозвать версию для aarch64

Ну и тогда называться должно x86,x64,ARM64 (в терминологии вижуалстудии. или в терминологии линукс-дистрибутивов - i686,AMD64,AARCH64)

А обозначения x86-32/x86-64/ARM64 я использую так как так проще было называть установщик, не надо название хардкодить под каждую комбинацию архитектура+разрядность

zvezdochiot commented 1 month ago

@plzombie , :question: так почему не "win-x86-64"? К чему тут "win32"? "32" что значит?

plzombie commented 1 month ago

Потому что API называется Win32

zvezdochiot commented 1 month ago

@plzombie , ага, вот теперь наконец распарсил. Ну и "мудрень". X0

noobie-iv commented 1 month ago

@zvezdochiot

Доп. матариал

Не поможет. Я не собираюсь сделать работающую "такую же, но проще" версию. Я хочу понять, как работает ST. Мне хватит пары примитивных фильтров, но чтобы в принципе они были устроены как в оригинале.

По факту я потихоньку копипащу код из ST, пока не получится минимально работающее главное окно с центральной картинкой и превьюшками. Потом можно будет попробовать встроить туда макетирование. А потом по аналогии сделать то же в ST.

На сегодня у меня есть пустое главное окно с панельками, и полтора десятка классов типа "Получатель", "Возвращатель полученного", "Передаватель возвращенного", "Возвращатель переданного возвращенного обратно получателю через представителя", "Подставной представитель", "Поручитель подставного представителя", "Приниматель поручителя", и т.д. по списку. Программа по-прежнему не делает ничего полезного, а классы пока только ссылаются друг на друга, ни в одном из методов не заканчиваясь хоть каким-то реальным действием. На подходе, видимо, еще десяток-другой аналогичных бездельников.

Когда я для теста извлекал деварп, я так больше мегабайта кода вынужден был скопипастить, чтобы он только компилировался; я даже не стал проверять, что он вообще работает. Если тут придется мегабайт с нуля набрать - это мне лет на десять работы выйдет. Пока я не вижу ни одного реального действия в программе, и не могу понять, что тогда все эти "Абстрактно-теоретические заменители реальности" делают. Пока что происходящее напоминает мне известный FizzBuzzEnterpriseEdition

zvezdochiot commented 1 month ago

@noobie-iv say:

Я не собираюсь сделать работающую "такую же, но проще" версию.

Ну это ты зря. Многие поклоники SK спят и видят, когда же кто-нибудь "придумает" STM (Scan Tailor Mini), занимающийся только разрезкой, преобразованиями и выравниванием. Это и к твоим целям более ближе: нарезал, выпрямил и выровнял, а дальше в любом редакторе делай что хочешь.

Сам же щаз думаю, как бы на этапе 3 "Геометрические преобразования" прикрутить индивидуальный масштабный фактор (по умолчанию 1.0000). Своего рода выравнивание DPI без самого DPI. И нужно именно на 3-ем этапе (в крайнем случае на 4ом, но на 4ом логика этого коэфициента теряется). Такие вот дела.

noobie-iv commented 1 month ago

@zvezdochiot

Scan Tailor Mini

Для таких желающих достаточно в ST перевести картинки в цветной режим.

дальше в любом редакторе

Любой редактор тем и неудобен, что не дает списка листов и повторной пакетной обработки по ним. Фишка ST же в том и есть, что он все в одном за три щелчка может. Вот только набор фукнций лично мне маловат, отсюда и страдания.

на этапе 3 "Геометрические преобразования" прикрутить индивидуальный масштабный фактор

Минимум два надо - по X и Y. Здешний деварп слишком любит пропрорции корежить.

plzombie commented 1 month ago

Кто-нибудь может мне в фотошопе сохранить TIFF со слоями? Хочу сравнить с тем, что делает GIMP (тупо несколько страниц с X/YPosition)