Я ваш 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<>, то я же не могу в нужном месте обернуть в AutoPtr, как только выйдем из области видимости, сразу пришибет мой image.

Если же мне нужно долгоживущее image (потому что я пишу много файлов и этот буфер переиспользую), то приходится поступать по полной программе:

// MyClass.h
#include "dng_image.h"
class MyClass {
private:
  AutoPtr<dng_image> image;
};

То есть по факту, ради индусов неаккуратных программистов, которым нельзя давать в руки указатель без презерватива страхующей обертки - я вынужден приносить потроха dng_image в объявление класса (а не в implementation), добавлять себе времени компиляции, засирать пространство имен везде. Эх.

Ну либо (как, наверное, подразумевается) каждый раз пересоздавать буфер.

Нет, я понимаю, C++ - сложный язык. Но зачем ТАК?

Comments

А у этого AutoPtr нет метода, аналогичного auto_ptr::release, который отпускает сырой указатель? Тогда было бы достаточно перед вызовом аттачить, после вызова отпускать.

Читаю вот сорцы, вроде бы так сработает действительно. Ну ок, простим им.

Королева в восхищении!!!

void dng_negative::SetStage1Image (AutoPtr<dng_image> &image)
    {   
    fStage1Image.Reset (image.Release ());    
    }

У меня, сука, забирают мой буфер. И потом его, сука, освободят.

То есть натурально, если у меня 100 одинаковых файлов, то мне надо 100 раз аллоцировать одинаковый (ну скажем 80-мегабайтный) буфер, а SDK будет его отнимать у меня и освобождать.

Ненавижу когда так строят. Без мозга.

Да, это от души.

Если не ошибаюсь, то при использовании стандартного auto_ptr достаточно иметь реализацию деструктора в cpp. Даже по-умолчанию: MyClass::~MyClass() = default. С адобовским не так?

Я C++ тоже труба шатал, поэтому не понял ответа.

Мне не нужна "реализация деструктора", мне нужно чтобы деструктор (никогда) не звался, ибо у меня долгоживущий указатель.

Со стандартным (c++11) auto_ptr такое вот компилируется:

// MyClass.h
class dng_image;
class MyClass {
private:
std::auto_ptr image;
};

// MyClass.cpp
MyClass::~MyClass() {
}

Можно попробовать с AutoPtr.

std::auto_ptr image; --> std::auto_ptr image

Только компилятор должен ругаться что std::auto_ptr — deprecated ;-)

Сорян. Даже и не знаю как такое написал
Конечно ж unique_ptr

Я бы тебя сейчас отправил школьную парту^W^Wслушайть кейноты последних лет с C++ conf. Где красной нитью — никаких raw pointers. По многим причинам. И это правильно.

Единственный грех DNG SDK — что это не std::shared_ptr а какой-то свой AutoPtr. Но SDK старше новых версий стандарта языка.

Пусть идут в жопу вместе с C++ conf.

Я хорошо знаю, какой у моих pointers срок жизни и аккуратно с ними управляюсь (когда мне безразлично или не хочу об этом думать - да, есть auto/shared/unique).

А мудизм этот, когда вместо reuse буфера получается реаллокация (потому что SDK хватает его и освобождает сам) - это в чистом виде мудизм.

Так. Давай мух отдельно а котлеты отдельно.

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

*Из дальнейшего обсуждения* мы видим, что используют вообще неправильно. Тут должен быть unique_ptr, который сразу бы показал тебе их намерение, без залезания в их код — стало бы чисто по API понятно, что дуфер у тебя отнимут. Если бы raw pointer был то осталась бы неоднозначность, с unique_ptr неоднозначности бы не было (а вот описанная тобой проблема declaration vs definition могла бы быть!).

Так же *из дальнейшего обсуждения* мы видим, что лично тебе семантика их API (передача управления буфером внутрь SDK) не подходит. Это вообще перпендикулярно тому, как передаётся указатель — в сыром виде или завёрнутый во что-то. Правильный ли это подход — я не знаю, в разных ситуациях может быть по разному, тебе неудобно, в другой ситуации может быть удобно. В простых приложениях на мой взгляд удобнее.

А не можешь ли ты потом передать туда NULL, что бы отобрать права назад? ;-)

P.S. Теги, конечно, в комментариях можно, только их потом не видно. Пришлось добавить звёздочки.

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

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

Но зато теперь я знаю простой способ таки сделать EXIF (а не так, как это сделано в dngconvert) из RAW-файла.

Можно просто открыть исходный RAW (не DNG) при помощи DNG SDK же. EXIF при этом распарсится и его можно оттуда вытащить.

Так я поэкономил себе 30...150 (в зависимости от задачи) строчек говнокода "getExifTag(tag1, tag2...."

А, фиг, скорее всего не выйдет. Там AutoPtr внутри при выставлении нового удалит старое скорее всего. Да, пидарасы, конечно. Но не потому что AutoPtr используют.

Ощущение, что проще переписать их AutoPtr, выкинув всякие освобождения в функциях и деструкторах. Если, конечно, они его внутри интенсивно не используют.

Хрен там!
При передаче нового - старый освобождается. Сука.
Собственно, из кода очевидно.

Ну не буду закатывать солнце вручную больше, значит будет дрочить по четверть гигабайта на каждой итерации.

Уроды, блин. Понятно почему у hdrmerge своя писалка DNG.

Да, ожидаемо. Согласен, люди вообще не подумали про работу пачкой а не one shot.

Может проще будет сделать патчи к libtiff что бы у неё был режим DNG? Структура-то одна.

Ну там много ж "помимо" собственно TIFF: EXIF, Makernotes, XMP, превьюшки и т.п.
У Адобы оно конечно мудацкое, но там реально много, 2.5 мегабайта исходников.

Кроме того, DNG SDK мы и так с собой таскаем для всяких экзотических форматов (8-bit dng, к примеру), которые LibRaw не распаковывает.

Но поскольку лицензия там BSD, я в какой-то момент наиболее раздражающие места дохакаю (ну вот добавлю метод "забыть, сука, указатель, переданный ранее") и успокоюсь.

Вот уже начал:

        void ClearStage1Image() {
            fStage1Image.Release();
        }

Ну да, или так, даже проще.

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

Несмотря на "мудацкое" - оно работает, то есть при правильном использовании я не помню ни одной проблемы (ну там, "битые DNG", "кривые DNG").

Другой вот вопрос, что правильное использование должно включать в себя возможность reuse buffer.

Переписать/унаследоваться от их AutoPtr, добавить в конструктор флаг bAllowReuse=false, чтоб не ломать их внутренний код, поправить функции освобождения, чтобы озирались на этот флаг.

Трехстрочная добавка (см. выше) решает мою проблему.

А, ну если оно пускает к fStage1Image, тогда да.

Когда это опенсорс с BSD-лицензией меня куда-то не пускал?

Я прямо в члены класса (dng_negative) добавил себе вызов - и проблему решил.

Но вообще это место - protected, можно было и по человечески сделать :)

PS: зачем однако ругать индусов... код же растет поди из личного писания гр. Knoll'а ... даже если он ничего не пишет туда сам со времен самых первых версий, вряд ли это начали индусы - они максимум не хотят обидеть босса

Z / V

А вот если не задать DefaultCrop*, то DefaultCropArea в выводимом DNG будет иметь размеры 0,0