2014 dxdy logo

Научный форум dxdy

Математика, Физика, Computer Science, Machine Learning, LaTeX, Механика и Техника, Химия,
Биология и Медицина, Экономика и Финансовая Математика, Гуманитарные науки




 
 Два затыка с write-read PNG код на С++ для 16 битных данных
Сообщение13.12.2023, 19:28 
Аватара пользователя
Всю жизнь работал с 8 битными изображениями в PNG. Запись - чтение на основе бибилотеки PNG и примеров для 8 бит. Потребовалось работать с 16 битами.
Примера в сети не нашел и просто модифицировал старый код через байтовый хип, в результате запись в какой-то мере работает.
Более или менее работающий код записи в файл PNG.
(Посоветуйте теги, чтобы код выглядел, как в среде компиляции и отладки)
Код:
          // allocate a vector of row pointers
          unsigned char * hip = new unsigned char  [height*width*2];

   std::vector<unsigned char *> rowPtrs;
   rowPtrs.resize(height);

for (int y = 0; y<height; y++) rowPtrs[y] = &hip[y*width*2];

for (int y = 0; y < height; y++)
for (int x = 0; x < width; x++)
   {   
       unsigned short vl = img.Pixel(x, y, 0);
            hip[2*x + y*width*2] = (vl/256);
       hip[2*x + 1 +  y*width*2] = (vl%256);
   }

   // write the whole image
   png_write_image(png_ptr, &rowPtrs[0]);

Но несмотря на unsigned short Фотошоп считает, что первый бит вообще неинформационный. Но этот затык как бы не главный.
Вот код для чтения - формально читает, но не совсем то, что записано в файл. Скорее, совсем не то.
Код:
unsigned char* hip = new unsigned char[height * width * 2];
      std::vector<unsigned char*> rowPtrs;
      rowPtrs.resize(height);
      for (int y = 0; y < height; y++) rowPtrs[y] = &hip[y * width * 2];
      
      png_read_image(png_ptr, &rowPtrs[0]);
      
for (int y = 0; y < height; y++)
for (int x = 0; x < width; x++)
         {
unsigned short vl = 256 * hip[2 * x + y * width * 2] + hip[2 * x + 1 + y * width * 2];
img.Pixel(x, y, 0) = vl;
         }

С моей тчки зрения, я просто делаю обратную операцию, но на выхде все не то.

 
 
 
 Re: Два затыка с write-read PNG код на С++ для 16 битных данных
Сообщение13.12.2023, 21:34 
Аватара пользователя
Что такое png_ptr?

 
 
 
 Re: Два затыка с write-read PNG код на С++ для 16 битных данных
Сообщение14.12.2023, 15:11 
Аватара пользователя
Geen в сообщении #1622310 писал(а):
Что такое png_ptr?

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

 
 
 
 Re: Два затыка с write-read PNG код на С++ для 16 битных данных
Сообщение14.12.2023, 16:15 
Аватара пользователя
MGM в сообщении #1622382 писал(а):
Там куча параметров

Вы уверены, что указываете в этой структуре правильную битность?

 
 
 
 Re: Два затыка с write-read PNG код на С++ для 16 битных данных
Сообщение14.12.2023, 18:04 
Аватара пользователя
Geen в сообщении #1622390 писал(а):
MGM в сообщении #1622382 писал(а):
Там куча параметров

Вы уверены, что указываете в этой структуре правильную битность?

Это, да. Там просто и для чтения, и для записи есть ветвление с этим параметром.
Кроме того, записанный файл распознается фотошопом, как 16 битный, и картинка очень похожа на тестовую последовательночть, которую я сгенерил. Только старший бит режется. Но мне он и не нужен. Данные все равно по сути 12 бит.
А вот при чтении этого же файла программа выдает сразуже какую-то лажу.
Другое дело, что библиотечные процедуры
Код:
png_read_image(png_ptr, &rowPtrs[0]);
и
Код:
png_read_image(png_ptr, &rowPtrs[0]);
из работающего примера требуют вторым параметром поинтер типа uchar **.
Возможно, есть что-то и для ushort **. Но цель была быстро переделать интерфейс из байтового в 16 битный. И запись сработала. А вот чтение как-то не очень. Первые строки вообще нулевые. Хотя тест просто равен значению индекса пикселя. Если бы была путаница в порядке следования старшего и младшего байта - все бы выглядело не так.

 
 
 
 Re: Два затыка с write-read PNG код на С++ для 16 битных данных
Сообщение14.12.2023, 20:44 
Аватара пользователя
Преодолел. Спасибо за внимание. Собственно код был верный. Но весь антураж с параметрами достаточно запутанный. Параметры зачем-то модифицируются после первого прочтения. Затем параметры структуры переделываются. В этот момент 16 бит превращаются в 8 бит.

 
 
 
 Re: Два затыка с write-read PNG код на С++ для 16 битных данных
Сообщение14.12.2023, 20:44 
Аватара пользователя
.

 
 
 [ Сообщений: 7 ] 


Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group