Example #1
0
/* Interrupt Service Routine */
void user_isr( void )
{
	/*T2IF = IFS0 8
	T2IE = IEC0 8
	T2IP = IPC2 26-28
	T2IS = IPC2 24/25
	*/
	//if interrupt clear T2IF and timer counter
	if(IFS(0) & 0x100){
	IFSCLR(0) = 0x100;
	TMR2 = 0;
	if(timeoutcount < 9){
		timeoutcount++;
	}else{
		//print on screen once a second
		timeoutcount = 0;
		time2string(textstring, mytime);
		display_string(3, textstring);
		display_update();
		tick(&mytime);
		//*portE += 1;
		//display_image(96, icon);
	}
}

	if(IFS(0) & 0x8000){
		IFSCLR(0) = 0x8000;
		*portE += 1;
	}
}
// delalying every 100 ms
void delaymillis(){
	
	T2CON = 0x70; // setting the prescale
	TMR2 = 0; // reset timer to 0
	T2CONSET = 0x8000; // turn timer on, set bit 15 to 1
	PR2 = TMR2PERIOD;

	IFS(0) = 0; // clear overflow flag
	// wait until overflow flag is set
	// display uodate only occurs once complete
	while(!(IFS(0) & 0x100));
	
}
Example #3
0
static HRESULT CreateOutputStream(const char* out_file_name,
                                  int write_to_mem, IStream** stream) {
  HRESULT hr = S_OK;
  if (write_to_mem) {
    // Output to a memory buffer. This is freed when 'stream' is released.
    IFS(CreateStreamOnHGlobal(NULL, TRUE, stream));
  } else {
    IFS(SHCreateStreamOnFileA(out_file_name, STGM_WRITE | STGM_CREATE, stream));
  }
  if (FAILED(hr)) {
    fprintf(stderr, "Error opening output file %s (%08lx)\n",
            out_file_name, hr);
  }
  return hr;
}
Example #4
0
static HRESULT OpenInputStream(const char* filename, IStream** ppStream) {
  HRESULT hr = S_OK;
  IFS(SHCreateStreamOnFileA(filename, STGM_READ, ppStream));
  if (FAILED(hr))
    printf("Error opening input file %s (%08x)\n", filename, hr);
  return hr;
}
Example #5
0
/* Adopted from the Dragon blanker */
LONG Blank( PrefObject *Prefs )
{
	struct Screen *Scr;
	struct Window *Wnd;
	LONG RetVal;
	
	if( Scr = OpenScreenTags( NULL, SA_Depth, Prefs[PREF_MODE].po_Depth,
							 SA_Quiet, TRUE, SA_DisplayID, Prefs[PREF_MODE].po_ModeID,
							 SA_Behind, TRUE, SA_Overscan, OSCAN_STANDARD,
							 TAG_DONE ))
	{
		SetRGB4(&( Scr->ViewPort ), 0, 0, 0, 0 );
		ColorTable = RainbowPalette( Scr, 0L, 1L, 0L );
		Wnd = BlankMousePointer( Scr );
		
		do
			RetVal = IFS( Scr, Scr->Width, Scr->Height, Prefs );
		while( RetVal == OK );
		
		UnblankMousePointer( Wnd );
		RainbowPalette( 0L, ColorTable, 1L, 0L );
		CloseScreen( Scr );
	}
	else
		RetVal = FAILED;
	
	return RetVal;
}
static HRESULT CreateOutputStream(const char* out_file_name, IStream** stream) {
  HRESULT hr = S_OK;
  IFS(SHCreateStreamOnFileA(out_file_name, STGM_WRITE | STGM_CREATE, stream));
  if (FAILED(hr)) {
    fprintf(stderr, "Error opening output file %s (%08lx)\n",
            out_file_name, hr);
  }
  return hr;
}
Example #7
0
/* Interrupt Service Routine */
void user_isr( void ) {

    timeoutcounter++;
    IFS(0) = 0;
    if(timeoutcounter % 10 == 0) {
        time2string( textstring, mytime );
        display_string( 3, textstring );
        display_update();
        tick( &mytime );
    }

}
Example #8
0
// Stores the first non-zero sized color profile from 'frame' to 'iccp'.
// Returns an HRESULT to indicate success or failure. The caller is responsible
// for freeing 'iccp->bytes' in either case.
static HRESULT ExtractICCP(IWICImagingFactory* const factory,
                           IWICBitmapFrameDecode* const frame,
                           MetadataPayload* const iccp) {
  HRESULT hr = S_OK;
  UINT i, count;
  IWICColorContext** color_contexts;

  IFS(IWICBitmapFrameDecode_GetColorContexts(frame, 0, NULL, &count));
  if (FAILED(hr) || count == 0) return hr;

  color_contexts = (IWICColorContext**)calloc(count, sizeof(*color_contexts));
  if (color_contexts == NULL) return E_OUTOFMEMORY;
  for (i = 0; SUCCEEDED(hr) && i < count; ++i) {
    IFS(IWICImagingFactory_CreateColorContext(factory, &color_contexts[i]));
  }

  if (SUCCEEDED(hr)) {
    UINT num_color_contexts;
    IFS(IWICBitmapFrameDecode_GetColorContexts(frame,
                                               count, color_contexts,
                                               &num_color_contexts));
    assert(FAILED(hr) || num_color_contexts <= count);
    for (i = 0; SUCCEEDED(hr) && i < num_color_contexts; ++i) {
      WICColorContextType type;
      IFS(IWICColorContext_GetType(color_contexts[i], &type));
      if (SUCCEEDED(hr) && type == WICColorContextProfile) {
        UINT size;
        IFS(IWICColorContext_GetProfileBytes(color_contexts[i],
                                             0, NULL, &size));
        if (SUCCEEDED(hr) && size > 0) {
          iccp->bytes = (uint8_t*)malloc(size);
          if (iccp->bytes == NULL) {
            hr = E_OUTOFMEMORY;
            break;
          }
          iccp->size = size;
          IFS(IWICColorContext_GetProfileBytes(color_contexts[i],
                                               (UINT)iccp->size, iccp->bytes,
                                               &size));
          if (SUCCEEDED(hr) && size != iccp->size) {
            fprintf(stderr, "Warning! ICC profile size (%u) != expected (%u)\n",
                    size, (uint32_t)iccp->size);
            iccp->size = size;
          }
          break;
        }
      }
    }
  }
  for (i = 0; i < count; ++i) {
    if (color_contexts[i] != NULL) IUnknown_Release(color_contexts[i]);
  }
  free(color_contexts);
  return hr;
}
Example #9
0
/* Interrupt Service Routine */
void user_isr( void )
{
  IFS(0) = 0 << 8; // Sätter interrupt flag till 0
  timeoutcount += 1; // 

  if (timeoutcount == 10) {

    time2string ( textstring, mytime );
    display_string( 3, textstring );
    display_update();
    tick( &mytime );
    timeoutcount = 0;
 
  }
  return;
}
Example #10
0
/* initialization routine */
void init (void) {
  /* turn spi off and clear interrupts */
  SPI2CON = 0;
  IEC(1) = 0;
  IPC(7) = 0;
  IFS(1) = 0;

  /* set interrupts */
  IPC(7) = (7<<24);
  IEC(1) = (1<<7);

  /* set spi */
  SPI2BRG = 0x1FF;      // Set SCK ~78kHz
  SPI2STATCLR = 0x40;   // Clear SPIROV bit
  SPI2CON = 0x8060;     // Set ON, CKE = 0, CKP = 1, MSTEN = 1
  asm("ei");
}
Example #11
0
static HRESULT WriteUsingWIC(const char* out_file_name, int use_stdout,
                             REFGUID container_guid,
                             uint8_t* rgb, int stride,
                             uint32_t width, uint32_t height, int has_alpha) {
  HRESULT hr = S_OK;
  IWICImagingFactory* factory = NULL;
  IWICBitmapFrameEncode* frame = NULL;
  IWICBitmapEncoder* encoder = NULL;
  IStream* stream = NULL;
  WICPixelFormatGUID pixel_format = has_alpha ? GUID_WICPixelFormat32bppBGRA
                                              : GUID_WICPixelFormat24bppBGR;

  IFS(CoInitialize(NULL));
  IFS(CoCreateInstance(MAKE_REFGUID(CLSID_WICImagingFactory), NULL,
                       CLSCTX_INPROC_SERVER,
                       MAKE_REFGUID(IID_IWICImagingFactory),
                       (LPVOID*)&factory));
  if (hr == REGDB_E_CLASSNOTREG) {
    fprintf(stderr,
            "Couldn't access Windows Imaging Component (are you running "
            "Windows XP SP3 or newer?). PNG support not available. "
            "Use -ppm or -pgm for available PPM and PGM formats.\n");
  }
  IFS(CreateOutputStream(out_file_name, use_stdout, &stream));
  IFS(IWICImagingFactory_CreateEncoder(factory, container_guid, NULL,
                                       &encoder));
  IFS(IWICBitmapEncoder_Initialize(encoder, stream,
                                   WICBitmapEncoderNoCache));
  IFS(IWICBitmapEncoder_CreateNewFrame(encoder, &frame, NULL));
  IFS(IWICBitmapFrameEncode_Initialize(frame, NULL));
  IFS(IWICBitmapFrameEncode_SetSize(frame, width, height));
  IFS(IWICBitmapFrameEncode_SetPixelFormat(frame, &pixel_format));
  IFS(IWICBitmapFrameEncode_WritePixels(frame, height, stride,
                                        height * stride, rgb));
  IFS(IWICBitmapFrameEncode_Commit(frame));
  IFS(IWICBitmapEncoder_Commit(encoder));

  if (SUCCEEDED(hr) && use_stdout) {
    HGLOBAL image;
    IFS(GetHGlobalFromStream(stream, &image));
    if (SUCCEEDED(hr)) {
      HANDLE std_output = GetStdHandle(STD_OUTPUT_HANDLE);
      DWORD mode;
      const BOOL update_mode = GetConsoleMode(std_output, &mode);
      const void* const image_mem = GlobalLock(image);
      DWORD bytes_written = 0;

      // Clear output processing if necessary, then output the image.
      if (update_mode) SetConsoleMode(std_output, 0);
      if (!WriteFile(std_output, image_mem, (DWORD)GlobalSize(image),
                     &bytes_written, NULL) ||
          bytes_written != GlobalSize(image)) {
        hr = E_FAIL;
      }
      if (update_mode) SetConsoleMode(std_output, mode);
      GlobalUnlock(image);
    }
  }

  if (frame != NULL) IUnknown_Release(frame);
  if (encoder != NULL) IUnknown_Release(encoder);
  if (factory != NULL) IUnknown_Release(factory);
  if (stream != NULL) IUnknown_Release(stream);
  return hr;
}
Example #12
0
static HRESULT WriteUsingWIC(const char* out_file_name, REFGUID container_guid,
                             unsigned char* rgb, int stride,
                             uint32_t width, uint32_t height, int has_alpha) {
  HRESULT hr = S_OK;
  IWICImagingFactory* factory = NULL;
  IWICBitmapFrameEncode* frame = NULL;
  IWICBitmapEncoder* encoder = NULL;
  IStream* stream = NULL;
  WICPixelFormatGUID pixel_format = has_alpha ? GUID_WICPixelFormat32bppBGRA
                                              : GUID_WICPixelFormat24bppBGR;

  IFS(CoInitialize(NULL));
  IFS(CoCreateInstance(MAKE_REFGUID(CLSID_WICImagingFactory), NULL,
                       CLSCTX_INPROC_SERVER,
                       MAKE_REFGUID(IID_IWICImagingFactory),
                       (LPVOID*)&factory));
  if (hr == REGDB_E_CLASSNOTREG) {
    fprintf(stderr,
            "Couldn't access Windows Imaging Component (are you running "
            "Windows XP SP3 or newer?). PNG support not available. "
            "Use -ppm or -pgm for available PPM and PGM formats.\n");
  }
  IFS(CreateOutputStream(out_file_name, &stream));
  IFS(IWICImagingFactory_CreateEncoder(factory, container_guid, NULL,
                                       &encoder));
  IFS(IWICBitmapEncoder_Initialize(encoder, stream,
                                   WICBitmapEncoderNoCache));
  IFS(IWICBitmapEncoder_CreateNewFrame(encoder, &frame, NULL));
  IFS(IWICBitmapFrameEncode_Initialize(frame, NULL));
  IFS(IWICBitmapFrameEncode_SetSize(frame, width, height));
  IFS(IWICBitmapFrameEncode_SetPixelFormat(frame, &pixel_format));
  IFS(IWICBitmapFrameEncode_WritePixels(frame, height, stride,
                                        height * stride, rgb));
  IFS(IWICBitmapFrameEncode_Commit(frame));
  IFS(IWICBitmapEncoder_Commit(encoder));

  if (frame != NULL) IUnknown_Release(frame);
  if (encoder != NULL) IUnknown_Release(encoder);
  if (factory != NULL) IUnknown_Release(factory);
  if (stream != NULL) IUnknown_Release(stream);
  return hr;
}
Example #13
0
int scan_fd( char *key, int fd, char **val) {
	ssize_t s = 0;
	char *d = malloc( MAXREAD);
	int i = 0, j, ret = 0;

	if( -1 == (s = read( fd, d, MAXREAD)))
		goto ERROR;
	while( s) {
		// liest solange ein leeres zeichen da ist.
		while( IFS( d[i]))
			BUFREAD( i, s, d, fd, MAXREAD, ERROR);
		// vergleicht das naechste wort mit dem schluessel.
		j = 0;
		while( key[j] && d[i] == key[j]) {
			j++;
			BUFREAD( i, s, d, fd, MAXREAD, ERROR);
		}
		// wenn das letzte zeichen vom schluessel erreicht wurde,
		// stimmt der schluessel mit dem gescanten wort ueberein.
		if( !key[j] && ( d[i] == '=' || IFS( d[i])))
			goto FOUND;
		while( !IFS( d[i]))
			BUFREAD( i, s, d, fd, MAXREAD, ERROR);
	}
	free( d);
	return 0;

FOUND:
	// key gefunden und der wert wird ausgegeben.
	if( d[i] == '=') {
		char *p;
		i++;
		for( j = 0; i+j < s && !IFS( d[i+j]); j++);
		if( !(p = malloc( j+1)))
			goto ERROR;
		memcpy( p, d+i, j);
		i = 0;
		if( !IFS( d[i+j])) {
			if( -1 == (s = read( fd, d, MAXREAD)))
				goto ERROR;
			if( s) {
				while( !IFS( d[i]) && s) {
					if( !( ++i < s)) {
						if( !(p = realloc( p, j+i+1)))
							goto ERROR;
						memcpy( p+j, d, i);
						j += i;
						if( -1 == (s = read( fd, d, MAXREAD)))
							goto ERROR;
						if( !s)
							break;
					}
				}
				if( !(p = realloc( p, j+i+1)))
					goto ERROR;
				memcpy( p+j, d, i);
			}
		}
		p[j+i] = 0;
		*val = p;
		ret = 1;
	}
	// key gefunden, hat aber keinen wert, der ausgegeben werden muss.
	else
		ret = 2;
	free( d);
	return ret;

ERROR:
	free( d);
	return -1;
}
Example #14
0
int ReadPictureWithWIC(const char* const filename,
                       WebPPicture* const pic, int keep_alpha,
                       Metadata* const metadata) {
  // From Microsoft SDK 6.0a -- ks.h
  // Define a local copy to avoid link errors under mingw.
  WEBP_DEFINE_GUID(GUID_NULL_, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
  static const WICFormatImporter kAlphaFormatImporters[] = {
    { &GUID_WICPixelFormat32bppBGRA_, 4, WebPPictureImportBGRA },
    { &GUID_WICPixelFormat32bppRGBA_, 4, WebPPictureImportRGBA },
    { NULL, 0, NULL },
  };
  static const WICFormatImporter kNonAlphaFormatImporters[] = {
    { &GUID_WICPixelFormat24bppBGR_, 3, WebPPictureImportBGR },
    { &GUID_WICPixelFormat24bppRGB_, 3, WebPPictureImportRGB },
    { NULL, 0, NULL },
  };
  HRESULT hr = S_OK;
  IWICBitmapFrameDecode* frame = NULL;
  IWICFormatConverter* converter = NULL;
  IWICImagingFactory* factory = NULL;
  IWICBitmapDecoder* decoder = NULL;
  IStream* stream = NULL;
  UINT frame_count = 0;
  UINT width = 0, height = 0;
  BYTE* rgb = NULL;
  WICPixelFormatGUID src_pixel_format = GUID_WICPixelFormatUndefined;
  const WICFormatImporter* importer = NULL;
  GUID src_container_format = GUID_NULL_;
  static const GUID* kAlphaContainers[] = {
    &GUID_ContainerFormatBmp,
    &GUID_ContainerFormatPng,
    &GUID_ContainerFormatTiff,
    NULL
  };
  int has_alpha = 0;
  int64_t stride;

  IFS(CoInitialize(NULL));
  IFS(CoCreateInstance(MAKE_REFGUID(CLSID_WICImagingFactory), NULL,
                       CLSCTX_INPROC_SERVER,
                       MAKE_REFGUID(IID_IWICImagingFactory),
                       (LPVOID*)&factory));
  if (hr == REGDB_E_CLASSNOTREG) {
    fprintf(stderr,
            "Couldn't access Windows Imaging Component (are you running "
            "Windows XP SP3 or newer?). Most formats not available. "
            "Use -s for the available YUV input.\n");
  }
  // Prepare for image decoding.
  IFS(OpenInputStream(filename, &stream));
  IFS(IWICImagingFactory_CreateDecoderFromStream(
          factory, stream, NULL,
          WICDecodeMetadataCacheOnDemand, &decoder));
  IFS(IWICBitmapDecoder_GetFrameCount(decoder, &frame_count));
  if (SUCCEEDED(hr) && frame_count == 0) {
    fprintf(stderr, "No frame found in input file.\n");
    hr = E_FAIL;
  }
  IFS(IWICBitmapDecoder_GetFrame(decoder, 0, &frame));
  IFS(IWICBitmapFrameDecode_GetPixelFormat(frame, &src_pixel_format));
  IFS(IWICBitmapDecoder_GetContainerFormat(decoder, &src_container_format));

  if (SUCCEEDED(hr) && keep_alpha) {
    const GUID** guid;
    for (guid = kAlphaContainers; *guid != NULL; ++guid) {
      if (IsEqualGUID(MAKE_REFGUID(src_container_format),
                      MAKE_REFGUID(**guid))) {
        has_alpha = HasAlpha(factory, decoder, frame, src_pixel_format);
        break;
      }
    }
  }

  // Prepare for pixel format conversion (if necessary).
  IFS(IWICImagingFactory_CreateFormatConverter(factory, &converter));

  for (importer = has_alpha ? kAlphaFormatImporters : kNonAlphaFormatImporters;
       hr == S_OK && importer->import != NULL; ++importer) {
    BOOL can_convert;
    const HRESULT cchr = IWICFormatConverter_CanConvert(
        converter,
        MAKE_REFGUID(src_pixel_format),
        MAKE_REFGUID(*importer->pixel_format),
        &can_convert);
    if (SUCCEEDED(cchr) && can_convert) break;
  }
  if (importer->import == NULL) hr = E_FAIL;

  IFS(IWICFormatConverter_Initialize(converter, (IWICBitmapSource*)frame,
                                     importer->pixel_format,
                                     WICBitmapDitherTypeNone,
                                     NULL, 0.0, WICBitmapPaletteTypeCustom));

  // Decode.
  IFS(IWICFormatConverter_GetSize(converter, &width, &height));
  stride = (int64_t)importer->bytes_per_pixel * width * sizeof(*rgb);
  if (stride != (int)stride ||
      !ImgIoUtilCheckSizeArgumentsOverflow(stride, height)) {
    hr = E_FAIL;
  }

  if (SUCCEEDED(hr)) {
    rgb = (BYTE*)malloc((size_t)stride * height);
    if (rgb == NULL)
      hr = E_OUTOFMEMORY;
  }
  IFS(IWICFormatConverter_CopyPixels(converter, NULL,
                                     (UINT)stride, (UINT)stride * height, rgb));

  // WebP conversion.
  if (SUCCEEDED(hr)) {
    int ok;
    pic->width = width;
    pic->height = height;
    pic->use_argb = 1;    // For WIC, we always force to argb
    ok = importer->import(pic, rgb, (int)stride);
    if (!ok) hr = E_FAIL;
  }
  if (SUCCEEDED(hr)) {
    if (metadata != NULL) {
      hr = ExtractMetadata(factory, frame, metadata);
      if (FAILED(hr)) {
        fprintf(stderr, "Error extracting image metadata using WIC!\n");
      }
    }
  }

  // Cleanup.
  if (converter != NULL) IUnknown_Release(converter);
  if (frame != NULL) IUnknown_Release(frame);
  if (decoder != NULL) IUnknown_Release(decoder);
  if (factory != NULL) IUnknown_Release(factory);
  if (stream != NULL) IUnknown_Release(stream);
  free(rgb);
  return SUCCEEDED(hr);
}
Example #15
0
static HRESULT ReadPictureWithWIC(const char* filename,
                                  WebPPicture* const pic, int keep_alpha) {
  HRESULT hr = S_OK;
  IWICBitmapFrameDecode* pFrame = NULL;
  IWICFormatConverter* pConverter = NULL;
  IWICImagingFactory* pFactory = NULL;
  IWICBitmapDecoder* pDecoder = NULL;
  IStream* pStream = NULL;
  UINT frameCount = 0;
  UINT width, height = 0;
  BYTE* rgb = NULL;
  WICPixelFormatGUID srcPixelFormat = { 0 };
  GUID srcContainerFormat = { 0 };
  const GUID* alphaContainers[] = {
    &GUID_ContainerFormatBmp,
    &GUID_ContainerFormatPng,
    &GUID_ContainerFormatTiff
  };
  int has_alpha = 0;
  int i, stride;

  IFS(CoInitialize(NULL));
  IFS(CoCreateInstance(MAKE_REFGUID(CLSID_WICImagingFactory), NULL,
          CLSCTX_INPROC_SERVER, MAKE_REFGUID(IID_IWICImagingFactory),
          (LPVOID*)&pFactory));
  if (hr == REGDB_E_CLASSNOTREG) {
    printf("Couldn't access Windows Imaging Component (are you running \n");
    printf("Windows XP SP3 or newer?). Most formats not available.\n");
    printf("Use -s for the available YUV input.\n");
  }
  // Prepare for image decoding.
  IFS(OpenInputStream(filename, &pStream));
  IFS(IWICImagingFactory_CreateDecoderFromStream(pFactory, pStream, NULL,
          WICDecodeMetadataCacheOnDemand, &pDecoder));
  IFS(IWICBitmapDecoder_GetFrameCount(pDecoder, &frameCount));
  if (SUCCEEDED(hr) && frameCount == 0) {
    printf("No frame found in input file.\n");
    hr = E_FAIL;
  }
  IFS(IWICBitmapDecoder_GetFrame(pDecoder, 0, &pFrame));
  IFS(IWICBitmapFrameDecode_GetPixelFormat(pFrame, &srcPixelFormat));
  IFS(IWICBitmapDecoder_GetContainerFormat(pDecoder, &srcContainerFormat));

  has_alpha = keep_alpha;
  for (i = 0;
       has_alpha && i < sizeof(alphaContainers)/sizeof(alphaContainers[0]);
       ++i) {
    if (IsEqualGUID(&srcContainerFormat, alphaContainers[i])) {
      has_alpha =
          IsEqualGUID(&srcPixelFormat, &GUID_WICPixelFormat32bppRGBA) ||
          IsEqualGUID(&srcPixelFormat, &GUID_WICPixelFormat32bppBGRA);
      break;
    }
  }

  // Prepare for pixel format conversion (if necessary).
  IFS(IWICImagingFactory_CreateFormatConverter(pFactory, &pConverter));
  IFS(IWICFormatConverter_Initialize(pConverter, (IWICBitmapSource*)pFrame,
          has_alpha ? MAKE_REFGUID(GUID_WICPixelFormat32bppRGBA)
                    : MAKE_REFGUID(GUID_WICPixelFormat24bppRGB),
          WICBitmapDitherTypeNone,
          NULL, 0.0, WICBitmapPaletteTypeCustom));

  // Decode.
  IFS(IWICFormatConverter_GetSize(pConverter, &width, &height));
  stride = (has_alpha ? 4 : 3) * width * sizeof(*rgb);
  if (SUCCEEDED(hr)) {
    rgb = (BYTE*)malloc(stride * height);
    if (rgb == NULL)
      hr = E_OUTOFMEMORY;
  }
  IFS(IWICFormatConverter_CopyPixels(pConverter, NULL, stride,
          stride * height, rgb));

  // WebP conversion.
  if (SUCCEEDED(hr)) {
    int ok;
#ifdef WEBP_EXPERIMENTAL_FEATURES
    if (has_alpha) {
      pic->colorspace |= WEBP_CSP_ALPHA_BIT;
    }
#endif
    pic->width = width;
    pic->height = height;
    ok = has_alpha ? WebPPictureImportRGBA(pic, rgb, stride)
                   : WebPPictureImportRGB(pic, rgb, stride);
    if (!ok)
      hr = E_FAIL;
  }

  // Cleanup.
  if (pConverter != NULL) IUnknown_Release(pConverter);
  if (pFrame != NULL) IUnknown_Release(pFrame);
  if (pDecoder != NULL) IUnknown_Release(pDecoder);
  if (pFactory != NULL) IUnknown_Release(pFactory);
  if (pStream != NULL) IUnknown_Release(pStream);
  free(rgb);
  return hr;
}