Graphics Exporters - Creating 16-bit-per-channel image files

Q: Can QuickTime Graphics Exporters create 16-bit-per-channel images?

A: Yes, the PNG and TIFF Graphics Exporters can create 16-bit-per-channel image files given a 16-bit-per-channel pixmap. Refer to Technical Q&A QA1114, '48 bit & 64 bit Pixel Format support in QuickTime' for a discussion of 16-bit-per-channel pixel format support.

IMPORTANT: These same Graphics Exporters will not create 16-bit-per-channel image files given 8-bit-per-channel pixmaps.

In order to make this work however, the depth value you should set when calling GraphicsExportSetDepth looks as though you are asking for an 8-bit-per-channel image file. See Table 1.

While it seems like the obvious values for GraphicsExportSetDepth would be k16GrayCodecType, k32AlphaGrayCodecType, k48RGBCodecType and k64ARGBCodecType respectively, these choices do not currently (QuickTime 6.5.1) produce the desired output.

Table 1:

PixMap and image file depthPixelFormat for GraphicsExportSetDepth
16-bit greyscalek8IndexedGrayPixelFormat
32-bit alpha+greyscalek32ARGBPixelFormat
48-bit rgbk24RGBPixelFormat
64-bit alpha+rgbk32ARGBPixelFormat

Listing 1: Exporting 48-bit RGB source.

// Use with the ImproveYourImage sample, see references below.

#include "MacShell.h"

void ExportDeepImageAsTIFF(void)
{
    Handle hOpenTypeList = NewHandle(0);
    long   numTypes = 0;
    FSSpec theFSSpec;
    Boolean isSelected, isReplacing;
    GraphicsImportComponent importer = 0;
    GraphicsExportComponent exporter = 0;
    Rect naturalBounds;
    unsigned long actualSizeWritten;
    ImageDescriptionHandle desc = NULL;
    Handle h = NULL;
    OSType pixelFormat;
    GWorldPtr gworld = NULL;
    OSErr err = noErr;

    BuildGraphicsImporterValidFileTypes(hOpenTypeList, &numTypes);
    HLock( hOpenTypeList );

    err = GetOneFileWithPreview(numTypes, (OSTypePtr)*hOpenTypeList, &theFSSpec, NULL);
    DisposeHandle(hOpenTypeList);
    if (err) return;

    // locate and open a graphics importer component
    err = GetGraphicsImporterForFile(&theFSSpec, &importer);
    if (err) return;

    // find out the real colorspace
    err = GraphicsImportGetImageDescription(importer, &desc);
    if (err) goto bail;

    err = GetImageDescriptionExtension(desc, &h, kImageDescriptionColorSpace, 1);
    DisposeHandle((Handle)desc);
    if (err) goto bail;
    if( !h || !*h ) goto bail;

    pixelFormat = *(OSType*)*h;
    pixelFormat = EndianU32_BtoN(pixelFormat);
    DisposeHandle(h);

    // if the imported image is 48-bit RGB,
    // export it as a 16-bit-per-channel TIFF file
    if (k48RGBCodecType == pixelFormat) {

        // draw the image into an offscreen gworld of that colorspace
        err = GraphicsImportGetNaturalBounds(importer, &naturalBounds);
        if (err) goto bail;

        err = QTNewGWorld(&gworld, pixelFormat, &naturalBounds,
                           NULL, NULL, kICMTempThenAppMemory);
        if (err) goto bail;

        err = GraphicsImportSetGWorld(importer, gworld, NULL);
        if (err) goto bail;

        err = GraphicsImportDraw(importer);
        if (err) goto bail;

        // write the image out as a tiff file
        err = PutFile("\pSave the image as:", "\pTest.tiff", &theFSSpec,
                       &isSelected, &isReplacing);
        if (err) goto bail;

        // find and open the TIFF Graphics Exporter component
        err = OpenADefaultComponent(GraphicsExporterComponentType, kQTFileTypeTIFF,
                                     &exporter);
        if (err) goto bail;

        // set the input source
        err = GraphicsExportSetInputGWorld(exporter, gworld);
        if (err) goto bail;

        // set the export destination
        err = GraphicsExportSetOutputFile(exporter, &theFSSpec);
        if (err) goto bail;

        // set the export depth, see table 1 in QA1345
        err = GraphicsExportSetDepth(exporter, k24RGBPixelFormat);
        if (err) goto bail;

        // export the file
        GraphicsExportDoExport(exporter, &actualSizeWritten);
    }

bail:

    if (importer) CloseComponent(importer);
    if (exporter) CloseComponent(exporter);
    if (gworld) DisposeGWorld(gworld);
}

References:

Back to Top 

Document Revision History

DateNotes
2004-06-03Discusses how to use QuickTime Graphics Exporters to create 16-bit-per-channel image files.

Posted: 2004-06-03


Did this document help you?
Yes: Tell us what works for you.
It’s good, but: Report typos, inaccuracies, and so forth.
It wasn’t helpful: Tell us what would have helped.