Программирование

Настройка Qt Creator для разработки под андроид: быстрый старт под Windows

Записки для себя, но вдруг кому будет полезно: есть многочисленные интернетные гайды, но они все - неизвестного времени, а многое - поменялось....

Загорелось мне тут сделать программу одну для телефона, чисто для себя. Ну, понятно, Qt+QML, потому что Qt я знаю, QML видел издалека, ничего сложного не запланировано. Как и всегда, главный вопрос "как начать" (т.е. настроить все, чтобы оно работало, компилировало, загружало в телефон/эмулятор), я на него потратил минимум...

Два слова про libtiff

Все-таки вот загадочная вещь этот ваш libtiff.

TIFF-файлы, как мы знаем, бывают tiled, бывают striped, а бывают одним куском (это, конечно, один страйп и никак иначе). Когда оно одним куском - стандартно собранная libtiff умеет эмулировать страйпы вменяемого размера (для тех, кто читает полосками), но речь не об этом.

Понятно что striped - это частный случай tiled, просто тайлы имеют ширину со все изображение. Но не наоборот.

И вот допустим некто (то есть я) хочет читать картинку банальным TIFFReadScanline(), но...

Снова трудо-выебудни

Повозившись сначала с libpng (формат простой и если следовать заложенным там идеям, то как бы и ничего так), а затем в libtiff (формат, как мы знаем, весьма развесистый)....

Я начинаю понимать популярность всяких OpenImageIO, FreeImage, ну на худой конец стандартных кодеков типа Qt-шных (говоришь ему read("file.png") оно само разберется что и куда).

Потому что та же libtiff - это, на самом деле, тихий ужас:

  • Есть TIFFReadRGBAImageOriented, которая может многое (Grayscale, RGB, Lab, CMYK - все вернет в виде RGBA). Правда с Lab/CMYK оно делает это как-то криво...., а какие-нибудь 12-битные RGB или 16-bit FP вовсе не умеет.
    Правда интерфейс там такой, что если исходный TIFF повернут на 90 градусов, результат TIFFReadRGBAImageOriented вас сначала огорчит, а потом (когда поймете отчего он такой) позабавит.
  • Поэтому есть TIFFReadSсanline - и можно читать по строчкам.
    Правда бывают TIFF-файлы, где строчек нет, а есть тайлы
  • Поэтому есть TIFFReadTile и можно читать тайлы.... ну уже криво, тайлу надо давать буфер под тайл, поместить его прямо в выходной растр нельзя, придется копировать.
    Правда бывают файлы, где цветовые компоненты записаны отдельно....
    Правда бывают файлы с тегом TIFFTAG_IMAGEDEPTH (про который я вообще не нашел ничего вменяемого за две минуты - и успокоился)

И вот не знать бы этих всех подробностей бы.....

И это как бы не говоря о том, что для striped/tiled tiffs конечно бы декодировать их многопоточно бы (чего libtiff не умеет).

Ну то есть мы тут все привыкли, что в RAW - бардак, ну OK. Но, э, если смотреть на "индустриальный стандарт" (TIFF и libtiff как имплементацию) - ну тоже невозможно сказать что все хорошо, ну то есть для чтения FP16-tiled-RGB tiff придется самому написать большую гору кода.

Трудо-выебудни

А вот, например, Adobe Bridge:

  1. Читает TIFF-файлы (ура).
  2. Умеет их повернуть (тоже неплохо). Делает это сменой тега Orientation.
  3. Но: если в файле содержится несколько изображений (т.е. image pyramid в терминах фотошопа), то Orientation меняется только у IFD0.
  4. При этом стандарт конечно умалчивает "как правильно поворачивать TIFF", но поскольку в IFD1..n прочие описания изображения (ну там размер, BitsPerSample, etc) описывают данное "под"-изображение, логично думать что и Orientation там верный (если этот тег есть, понятно что если его нет, то надо
  5. ...

Душераздирающее о Qt

Я на это уже жаловался, но в фейсбуке, а не тут.

Но просматривая сегодня Qt mailing lists/development не смог пройти мимо:

Несчастный пользователь пишет:

I'd like to point out how badly this issue has been handled. It's been reported on February 2016 and marked as P4.To me, it seems a nonsense to ignore issues like this, especially now that Qt3D offers a lot of possibilities and sooner or later you might need to switch your app to core profile....

Про Qt

1 апреля 2014 года я порепортил (очередной) баг в Qt4

Прошло 4.5 года, его наконец закрыли:

Thank you for the report. Qt 4 is no longer supported, please check if this is still an issue with a recent Qt 5 version, in which case you can re-open this report.

Молодцы, че.

Ссылок не даю, потому что не единственный случай, а паттерн всегда один и тот же:

  • В актуальной (на момент репорта) версии - всем насрать (я уже воспроизводить-репортить начал в свежих из принципа)
  • Через несколько лет - отписка "эта версия не поддерживается, попробуйте в новой"

Дать им денег что ли, может будет иначе....

AVX2 speedup

На одном и том же CPU (i7-7700k на базовых частотах), переход с SSE3 на AVX2 дает выигрыш, если по отдельным кускам:

  • Half-демозаика + ББ + цветовая конверсия + тоновая кривая, запись RGB bitmap: 1.97/1.11 sec (SSE/AVX)
  • Half-демозаика + ББ + цветовая конверсия + построение гистограммы: 2.11/1.483
  • Чтение raw-данных (int16), преборазование в float, вычитание черного, построение RAW-гистограммы: 1.78/1.72. Гистограмма - это очень медленно.....

Тестовый набор: 22 файла Sony A7RM2, т.е. ~900Mpix в сумме. Чиселки - CPU time (не wall time, потому что мультитрединг).

Общий выигрыш на всю программу - не больше 10 процентов, потому что уперлись теперь в видеодрайвер (генерация мипмепов, загрузка текстур в видеокарту), все спинлоки - тама.  Надо более продвинутый OpenGL использовать.

 

Про AVX2 и размывание кэшей

Вот наконец удалось ощутить офигенную пользу от AVX2, причем двойную. Вот такой вот код:

_mm256_stream_si256((__m256i *)&drowp[col], _mm256_i32gather_epi32((const int*)table, _mm256_cvttps_epi32(_mm256_load_ps(&srowp[col])), 4));

в 4.5-5 раз быстрее, чем простой SSE2 аналог (в котором, понятно, нет gather) и в ~6 раз быстрее скалярного C-кода:

drowp[col] = table[(unsigned)srowp[col]];

Рассмотрение всего хозяйства под микроскопом показало, что основной взнос в результат дает _mm256_stream, а вовсе не gather. Стоит заменить stream на store, как все сразу портится. По достаточно очевидной причине: длина строки и drowp и srowp -...

AVX(2) data load

Граждане, что-то вот отчаялся понять, отчего может быть так что

Вот так - хорошо, профайлер в этом месте особых тормозов не показывает:

                __m128 p0 = _mm_loadu_ps(source);
                __m128 p1 = _mm_loadu_ps(source + 4);
                __m128 p2 = _mm_loadu_ps(source + 8);

 

А вот так - нехорошо:

                __m256 i0008 = _mm256_loadu_ps(fsrcstart3);
                __m256 i0915 = _mm256_loadu_ps(fsrcstart3 + 8);
                __m256 i1623
...

Я ваш Adobe DNG SDK труба шатал!

Продолжаю биться головой о стену DNG SDK .

Вот, к примеру, объявление функции

void dng_negative::SetStage1Image (AutoPtr<dng_image> &image);

Вот как я обычно делаю:

// MyClass.h class dng_image; // Никаких include "dng_.....h", просто forward declaration class MyClass { private: dng_image *image; };

И только там, где у меня implemetation для MyClass - там будет включено "dng_image.h" и мы, наконец, разберемся, что же это такое (а указатель... ну указатель, 4/8 байт, нечего про него знать, private)

Но если интерфейс у dng_negative требует AutoPtr<>,...

Трудовые будни

Вот решил я для экономии памяти - для распаковки JPEG иметь буфер на одну строчку и сразу распихивать ее куда надо (в tiled-буферы с перекрытиями).

Как мне повезло, что тестировать-отлаживать я начал на progressive JPEG......

Записки сумасшедшего: Qt+OpenGL

Мы продолжаем наш репортаж про Qt и OpenGL.

В Qt, если кто не знает, есть приятные врапперы для OpenGL. QOpenGLShaderProgram для шейдеров, QOpenGLBuffer для буферов ну и так далее. Я ими пользуюсь, потому что удобно, сахарок вкусный типа QOpenGLVertexArrayObject::Binder, опять же деструкторы все удалят и так далее.

И есть QOpenGLTexture, любовь с ней в FRV у меня не задалась (делаю все руками в результате), а тут в рамках HelloWorld-2017 решил вернуться к ней.

И получился (почти)...

Если к кошке приставить голову тигра....

Каких-то жалких 4.5 года назад KDAB начали рекламировать использование современного OpenGL изнутри Qt.

Я их начитался еще тогда и возжелал. Однако требования к железу (OpenGL 3.3/DirectX 11) поднимать в FastRawViewer не хотелось и руки дошли вот только сейчас, для нового проекта, благо железо подросло и OpenGL 3.3 есть во всем вменяемом (включая Intel, кто до сих пор работает на SandyBridge с тамошним видео - пусть страдает).

Однако научные исследования показали, что реально OpenGL CoreProfile так чтобы все...

"Hello world" - 2017

Вот значит написал программу, которая ничего (почти) не делает:

$ cat *.cpp *.h *.pro *.frag *.vert *.qrc | wc -l 3584

Нельзя сказать, что совсем уж ничего:

  • Окошко есть
    • в окошко выводит OpenGL (или OpenGL ES 3 поверх DX11). Разноцветный треугольник, что еще можно выводить.
    • и конечно с шейдерами, их компиляцией, сохранением/загрузкой бинарного представления и т.п.
    • и сolor management есть (и сохранение/чтение device link LUT, чтобы каждый раз не пересчитывать таблицу)
    • настройки есть, их чтение, сохранение, редактирование (втч.
  • ...

30 лет в строю

Я, конечно, не красный граф и не могу пока с ним меряться трудовым стажем.

Однако где-то в этих числах ноября 1987-го года, то есть 30 лет назад, я получил свою первую зарплату за программирование. На биофаке МГУ, в Налимовской лаборатории, что-то там программировал по "планированию факторного эксперимента".

Не помню что программировал, не помню на чем (но процентов 90 за фортран-77), а вот зарплату первую помню и как в здании биофака заблудился, зарплату получив, - тоже помню. И IBM PS/2 Model 50 помню прекрасно (как-то меня пронесло мимо ДВК/PDP, сразу началось с ЕС ЭВМ и дальше PC).

Но с тех пор - не останавливался. Так и программирую за деньги (программировать просто так я начал, понятно, раньше).

А благодарить надо школу, ибо все началось на УПК, на специальности "оператор ЭВМ".

Лучшее - враг....

After Qt 5.3’s introduction of QQuickWidget, Qt 5.4 adds QOpenGLWidget, the long-awaited replacement for the legacy QGLWidget.

Писали нам в Qt Weekly три года назад.

Я тогда попробовал, но Qt 5.4 глючила на маке (уже не помню даже в каком месте), держать две ветки кода было не с руки, так и используем legacy QGLWidget в FRV.

Прошло три года и руки дошли попробовать еще раз, уже в Qt 5.6. Такой вот бутерброд (если вкратце):

QGraphicsView...

Q: Win32 CryptAPI

Граждане программисты,

а ткните носом, как проверить валидность подписи EXE-файла (MS Authenticode) без WinVerifyTrust, а с использованием только CryptoAPI. Ведь должно же быть можно?

Трудовые будни

А вот вы знали, что Adobe XMP SDK может в некоторых случаях при записи XMP модифицировать еще и EXIF у файла?

И я не знал.

А поскольку случаи - некоторые, то в наших тестах оно как-то не вылезло (дальше нецензурно).

Разборки показали, что это, смешно сказать, рекомендованное поведение:

When the file format supports both Exif and XMP, a Changer SHOULD update both forms of a value. If only
...

О программистах и пользователях

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

Вот есть такая библиотека декодирования RAW, RawSpeed. Хорошая, в том смысле что быстрая, местами сильно быстрее LibRaw, местами - не сильно. Ее сначала разрабатывал Клаус Пост, а потом, весной где-то, передал текущей команде darktable.

И вот ее теперешний майнтайнер берет и одним движением вставляет дополнительную проверку на размер изображения, например вот эту: ...

Удивительное рядом (о совместимости ABI компиляторов)

Волею судеб тут пришлось делать следующие упражнения:

  • Собрать некую библиотеку (C++) с помощью Visual Studio 2013 тулсетом для XP (Platform toolset: v120_xp) и использовать ее потом из Visual Studio 2010.
  • Собрать некую библиотеку (C++) с помощью Clang (clang-cl, версия 4.0.1) и использовать (вызывать) ее потом из кода, собираемого Visual Studio (в данном случае 2015, но думаю проделать то же с 2010 и 2013). А из clang-собранной библиотеки зовется еще одна, собранная 2015-й студией.

Причина была одна и та же, первая "некая библиотека" не собирается 2010й студией, ибо используемый C++ новее, аналогично и со второй (сходу только Clang/gcc, под MSVC надо править, но очень уж не хотелось).

На удивление, оба варианта проканали вообще без каких-то проблем (я опасался, что придется тянуть всякие чужие C/C++ рантаймы, но нет). Про Clang известно, что над совместимостью по name mangling и подобному там все еще ведутся улучшения, но базовые вещи работают уже.

Еще более на удивление, с clang-cl работают базовые вещи у отладчика VisualStudio (небазовые не пробовал).

Итого: вот просто берешь и используешь (в случае Clang - запускаешь еще батник для интеграции с VS).

Вот что не работает с раздачи, так это cmake, которому указано что используется clang-овский toolset. Оно каким-то чудом узнает, что вот работает clang (хоть и -cl) и пытается совать туда clang-овские же свитчи командной строки, а clang-cl их не понимает. Надо править бы, но я этот ad-hoc язык не знаю и очень не хочу узнавать.

 

Pages

Subscribe to Программирование