nokiatech / heif

High Efficiency Image File Format
Other
1.74k stars 248 forks source link

A problem about iPhone heic #50

Closed crb912 closed 6 years ago

crb912 commented 6 years ago

Dear Nokia Developer, I know a typical iPhone heic picture has 48 tiles, and I extract all tiles into H.265 bitstream successful. Then I use ffmpeg convert them to png,I get all 48 still tiles picture finally. But it's not I wanted. I try to put all decoder tile into one memory buffer, just converting one times get the complete png picture. Because I think maybe I could get a picture, not 48 tile. But I don't know how to set the HEVC NAL Uint at the beganing of memory buffer. What should I do? Or the mathod cannot make it? My part code


Array<ImageId> gridIds;
Grid gridData;
Array<ImageId> tileItemIds;
if(reader->getItemListByType("grid",gridIds) == ErrorCode::OK)
{
    tileItemIds = gridData.imageIds;
    if(reader->getItem(gridIds[0].get(), gridData) == ErrorCode::OK)
        {
            tileItemIds = gridData.imageIds; // 48 tiles

            // Calculate size of parameter sets, but do not copy the data yet.
            size_t parameterSize = 0;
            DecoderConfiguration decodeConf;
             if(reader->getDecoderParameterSets(tileItemIds[0], decodeConf) == ErrorCode::OK)       
             // I konw the decodeConf is not I want 
            {
                for (auto& config : decodeConf.decoderSpecificInfo)
                {parameterSize += config.decSpecInfoData.size;}
            }

            //  Copy (worong)parameter data to the beginning of the buffer.
            uint64_t itemSize(0);
            size_t offset = 0;
            for (const auto& config : decodeConf.decoderSpecificInfo)
            {
                memcpy(memoryBuffer + offset, config.decSpecInfoData.begin(), config.decSpecInfoData.size);
                offset += config.decSpecInfoData.size;
            }
            itemSize = memoryBufferSize - static_cast<uint32_t>(parameterSize);

            // Copy all tiles data to the buffer
            size_t tileSize = 0;
            for (unsigned int i = 0; i < tileItemIds.size; i++)
            {

                if (reader->getItemData(tileItemIds[i].get(), &memoryBuffer[parameterSize+tileSize], itemSize) == ErrorCode::OK)
                {
                    cout << "Get the tile: " << i << endl;
                    tileSize += itemSize;
                    itemSize = memoryBufferSize - parameterSize - tileSize;
                }
                else{cout << "Get Image Data error!" << endl;}

                memoryBufferSize = static_cast<uint32_t>(parameterSize) + tileSize;

                ofstream outfile(file_name, ofstream::binary);
                outfile.write(memoryBuffer, memoryBufferSize);
            }
crb912 commented 6 years ago

I guess I could get a complete HEVC picture in this way. Am I wrong? image

Or I just need to configure Nal Uint in right way?

crb912 commented 6 years ago

When I run my code in the way, then:

 ffmpeg -i  outfile  abc.png

I just get a tile of the piture. 512 512 ppi ,not 40323024.

ly90590 commented 4 years ago

Hi, were you able to solve this issue?

myrao commented 3 years ago

I found my .heic file type is grid, this image was taken by iPhone, and I got more information about it: grid type heif file has many children images(size: 512x512), if we want generate a fully image, should tile these on canvas or container.