Example #1
0
static bool is_float_image(const string& filename)
{
	ImageInput *in = ImageInput::create(filename);
	bool is_float = false;

	if(in) {
		ImageSpec spec;

		if(in->open(filename, spec)) {
			/* check the main format, and channel formats;
			 * if any take up more than one byte, we'll need a float texture slot */
			if(spec.format.basesize() > 1)
				is_float = true;

			for(size_t channel = 0; channel < spec.channelformats.size(); channel++) {
				if(spec.channelformats[channel].basesize() > 1)
					is_float = true;
			}

			in->close();
		}

		delete in;
	}

	return is_float;
}
Example #2
0
static bool is_float_image(const string& filename)
{
	ImageInput *in = ImageInput::create(filename);
	bool is_float = false;

	if(in) {
		ImageSpec spec;

		if(in->open(filename, spec)) {
			/* check the main format, and channel formats;
			   if any are non-integer, we'll need a float texture slot */
			if(spec.format == TypeDesc::HALF ||
			   spec.format == TypeDesc::FLOAT ||
			   spec.format == TypeDesc::DOUBLE) {
				is_float = true;
			}

			for(size_t channel = 0; channel < spec.channelformats.size(); channel++) {
				if(spec.channelformats[channel] == TypeDesc::HALF ||
				   spec.channelformats[channel] == TypeDesc::FLOAT ||
				   spec.channelformats[channel] == TypeDesc::DOUBLE) {
					is_float = true;
				}
			}

			in->close();
		}

		delete in;
	}

	return is_float;
}
Example #3
0
void lux::readOIIOImage( const char* fname, Image& img  )
{
   int xres, yres, channels;
   ImageInput *in = ImageInput::create (fname);
   if (! in) {return;}
   ImageSpec spec;
   in->open (fname, spec);
   xres = spec.width;
   yres = spec.height;
   channels = spec.nchannels;
   float* pixels = new float[xres*yres*channels];
   in->read_image (TypeDesc::FLOAT, pixels);

   img.reset( xres, yres, channels );
   long index = 0;
   for( int j=0;j<yres;j++)
   {
      for( int i=0;i<xres;i++ )
      {
         for( int c=0;c<channels;c++ )
         {
	    img.value(i,img.Height() - j - 1,c) = pixels[index++];
         }
      }
   }
   in->close ();
   delete in;
   delete[] pixels;
}
void readOIIOImage( const char* fname, float* img  )
{
  int xres, yres, channels;
  ImageInput *in = ImageInput::create (fname);
  if (! in) {return;}
  ImageSpec spec;
  in->open (fname, spec);
  xres = spec.width;
  yres = spec.height;
  channels = spec.nchannels;
  float* pixels = new float[xres*yres*channels];

  in->read_image (TypeDesc::FLOAT, pixels);
  long index = 0;
  for( int j=0;j<yres;j++)
  {
    for( int i=0;i<xres;i++ )
    {
      for( int c=0;c<channels;c++ )
      {
        img[ (i + xres*(yres - j - 1))*channels + c ] = pixels[index++];
      }
    }
  }

  in->close ();
  delete in;
}
void
RawInput::read_tiff_metadata (const std::string &filename)
{
    // Many of these raw formats look just like TIFF files, and we can use
    // that to extract a bunch of extra Exif metadata and thumbnail.
    ImageInput *in = ImageInput::create ("tiff");
    if (! in) {
        (void) OIIO::geterror();  // eat the error
        return;
    }
    ImageSpec newspec;
    bool ok = in->open (filename, newspec);
    if (ok) {
        // Transfer "Exif:" metadata to the raw spec.
        for (ParamValueList::const_iterator p = newspec.extra_attribs.begin();
                p != newspec.extra_attribs.end();  ++p) {
            if (Strutil::istarts_with (p->name().c_str(), "Exif:")) {
                m_spec.attribute (p->name().c_str(), p->type(), p->data());
            }
        }
    }

    in->close ();
    delete in;
}
Example #6
0
static void
time_read_image ()
{
    ImageInput *in = ImageInput::open (input_filename.c_str());
    ASSERT (in);
    in->read_image (TypeDesc::TypeFloat, &buffer[0]);
    in->close ();
    delete in;
}
Example #7
0
static void
time_read_64_scanlines_at_a_time ()
{
    ImageInput *in = ImageInput::open (input_filename.c_str());
    ASSERT (in);
    const ImageSpec &spec (in->spec());
    size_t pixelsize = spec.nchannels * sizeof(float);
    imagesize_t scanlinesize = spec.width * pixelsize;
    for (int y = 0; y < spec.height;  y += 64) {
        in->read_scanlines (y+spec.y, std::min(y+spec.y+64, spec.y+spec.height),
                            0, TypeDesc::TypeFloat, &buffer[scanlinesize*y]);
    }
    in->close ();
    delete in;
}
Example #8
0
/**
 * @brief Read in images
 * @details Read foregournd and background images into program.
 *
 * @param image Image name to read in.
 */
void readImage(char *image) {

  // Open image input
  ImageInput *in = ImageInput::open(image);

  // Error handeling
  if (!in) {
    printf("Error reading image: %s\n", geterror().c_str());
    exit(EXIT_FAILURE);
  }

  // Get input spec
  const ImageSpec &spec = in->spec();

  // Get image details
  originalWidth = spec.width;
  originalHeight = spec.height;
  channels = spec.nchannels;

  // Init the global copy of the pixels
  // Read in the pixels and close the file
  oiioPixels.resize(originalWidth*originalHeight*channels*sizeof(float));
  in->read_image(TypeDesc::FLOAT, &oiioPixels[0]);
  in->close();
  delete in;

  // Initalize 2d array
  pixels = new rgba_pixel*[originalHeight];
  pixels[0] = new rgba_pixel[originalWidth*originalHeight];

  for (int i=1; i<originalHeight; i++) {
    pixels[i] = pixels[i-1] + originalWidth;
  }

  // Transfer into custom data structure
  for (int row = 0; row < originalHeight; row++)
    for (int col = 0; col < originalWidth; col++){
      pixels[row][col].r = oiioPixels[(row*originalWidth+col)*channels + 0];
      pixels[row][col].g = oiioPixels[(row*originalWidth+col)*channels + 1];
      pixels[row][col].b = oiioPixels[(row*originalWidth+col)*channels + 2];
      if(channels == 4) pixels[row][col].a = oiioPixels[(row*originalWidth+col)*channels + 3];
      else pixels[row][col].a = 1.0;
    }
}
Example #9
0
void lux::readOIIOImage( const char* fname, Image& img, map<string,string>& labels )
{
   int xres, yres, channels;
   ImageInput *in = ImageInput::create (fname);
   if (! in) {return;}
   ImageSpec spec;
   in->open (fname, spec);
   xres = spec.width;
   yres = spec.height;
   channels = spec.nchannels;
   float* pixels = new float[xres*yres*channels];
   in->read_image (TypeDesc::FLOAT, pixels);

   img.reset( xres, yres, channels );
   long index = 0;
   for( int j=0;j<yres;j++)
   {
      for( int i=0;i<xres;i++ )
      {
         for( int c=0;c<channels;c++ )
         {
	    img.value(i,img.Height() - j - 1,c) = pixels[index++];
         }
      }
   }

   for( size_t i=0;i<spec.extra_attribs.size();i++)
   {
      const ParamValue& p = spec.extra_attribs[i];
      string name = p.name().c_str();
      string value = spec.metadata_val ( p, true);
      labels[name] = value;
   }

   in->close ();
   delete in;
   delete[] pixels;
}
Example #10
0
//TODO go over this function to see if it can be refactored
void
TileCache::addSource( const std::string fileName )
{
    OIIO_NAMESPACE_USING;
    ImageInput *image = nullptr;
    if( (image = ImageInput::open( fileName )) ){
        image->close();
        delete image;

        _nTiles++;
        map.push_back( nTiles );
        fileNames.push_back( fileName );
        return;
    }

    SMT *smt = nullptr;
    if( (smt = SMT::open( fileName )) ){
        if(! smt->nTiles ) return;
        _nTiles += smt->nTiles;
        map.push_back( nTiles );
        fileNames.push_back( fileName );

        delete smt;
        return;
    }

    SMF *smf = nullptr;
    if( (smf = SMF::open( fileName )) ){
        // get the fileNames here
        auto smtList = smf->getSMTList();
        for( auto i : smtList ) addSource( i.second );
        delete smf;
        return;
    }

    LOG(ERROR) << "unrecognised format: " << fileName;
}
Example #11
0
bool
OiioTool::print_info (const std::string &filename,
                      const print_info_options &opt,
                      long long &totalsize,
                      std::string &error)
{
    error.clear();
    ImageInput *input = ImageInput::open (filename.c_str());
    if (! input) {
        error = geterror();
        if (error.empty())
            error = Strutil::format ("Could not open \"%s\"", filename.c_str());
        return false;
    }
    ImageSpec spec = input->spec();

    boost::regex field_re;
    boost::regex field_exclude_re;
    if (! opt.metamatch.empty()) {
        try {
            field_re.assign (opt.metamatch,
                             boost::regex::extended | boost::regex_constants::icase);
        } catch (const std::exception &e) {
            error = Strutil::format ("Regex error '%s' on metamatch regex \"%s\"",
                                     e.what(), opt.metamatch);
            return false;
        }
    }
    if (! opt.nometamatch.empty()) {
        try {
            field_exclude_re.assign (opt.nometamatch,
                                     boost::regex::extended | boost::regex_constants::icase);
        } catch (const std::exception &e) {
            error = Strutil::format ("Regex error '%s' on metamatch regex \"%s\"",
                                     e.what(), opt.nometamatch);
            return false;
        }
    }

    int padlen = std::max (0, (int)opt.namefieldlength - (int)filename.length());
    std::string padding (padlen, ' ');

    // checking how many subimages and mipmap levels are stored in the file
    int num_of_subimages = 1;
    bool any_mipmapping = false;
    std::vector<int> num_of_miplevels;
    {
        int nmip = 1;
        while (input->seek_subimage (input->current_subimage(), nmip, spec)) {
            ++nmip;
            any_mipmapping = true;
        }
        num_of_miplevels.push_back (nmip);
    }
    while (input->seek_subimage (num_of_subimages, 0, spec)) {
        // maybe we should do this more gently?
        ++num_of_subimages;
        int nmip = 1;
        while (input->seek_subimage (input->current_subimage(), nmip, spec)) {
            ++nmip;
            any_mipmapping = true;
        }
        num_of_miplevels.push_back (nmip);
    }
    input->seek_subimage (0, 0, spec);  // re-seek to the first

    if (opt.metamatch.empty() ||
            boost::regex_search ("resolution, width, height, depth, channels", field_re)) {
        printf ("%s%s : %4d x %4d", filename.c_str(), padding.c_str(),
                spec.width, spec.height);
        if (spec.depth > 1)
            printf (" x %4d", spec.depth);
        printf (", %d channel, ", spec.nchannels);
        if (spec.channelformats.size()) {
            for (size_t c = 0;  c < spec.channelformats.size();  ++c)
                printf ("%s%s", c ? "/" : "",
                        spec.channelformats[c].c_str());
        } else {
            int bits = spec.get_int_attribute ("oiio:BitsPerSample", 0);
            printf ("%s", extended_format_name(spec.format, bits));
        }
        if (spec.depth > 1)
            printf (" volume");
        printf (" %s", input->format_name());
        if (opt.sum) {
            imagesize_t imagebytes = spec.image_bytes (true);
            totalsize += imagebytes;
            printf (" (%.2f MB)", (float)imagebytes / (1024.0*1024.0));
        }
        // we print info about how many subimages are stored in file
        // only when we have more then one subimage
        if ( ! opt.verbose && num_of_subimages != 1)
            printf (" (%d subimages%s)", num_of_subimages,
                    any_mipmapping ? " +mipmap)" : "");
        if (! opt.verbose && num_of_subimages == 1 && any_mipmapping)
            printf (" (+mipmap)");
        printf ("\n");
    }

    if (opt.verbose && num_of_subimages != 1) {
        // info about num of subimages and their resolutions
        printf ("    %d subimages: ", num_of_subimages);
        for (int i = 0; i < num_of_subimages; ++i) {
            input->seek_subimage (i, 0, spec);
            if (spec.depth > 1)
                printf ("%dx%dx%d ", spec.width, spec.height, spec.depth);
            else
                printf ("%dx%d ", spec.width, spec.height);
        }
        printf ("\n");
    }

    // if the '-a' flag is not set we print info
    // about first subimage only
    if ( ! opt.subimages)
        num_of_subimages = 1;
    for (int i = 0; i < num_of_subimages; ++i) {
        print_info_subimage (i, num_of_subimages, spec, input,
                             filename, opt, field_re, field_exclude_re);
    }

    input->close ();
    delete input;
    return true;
}
Example #12
0
bool ImageManager::get_image_metadata(const string& filename,
                                      void *builtin_data,
                                      ImageMetaData& metadata)
{
	memset(&metadata, 0, sizeof(metadata));

	if(builtin_data) {
		if(builtin_image_info_cb) {
			builtin_image_info_cb(filename, builtin_data, metadata);
		}
		else {
			return false;
		}

		if(metadata.is_float) {
			metadata.is_linear = true;
			metadata.type = (metadata.channels > 1) ? IMAGE_DATA_TYPE_FLOAT4 : IMAGE_DATA_TYPE_FLOAT;
		}
		else {
			metadata.type = (metadata.channels > 1) ? IMAGE_DATA_TYPE_BYTE4 : IMAGE_DATA_TYPE_BYTE;
		}

		return true;
	}

	/* Perform preliminary checks, with meaningful logging. */
	if(!path_exists(filename)) {
		VLOG(1) << "File '" << filename << "' does not exist.";
		return false;
	}
	if(path_is_directory(filename)) {
		VLOG(1) << "File '" << filename << "' is a directory, can't use as image.";
		return false;
	}

	ImageInput *in = ImageInput::create(filename);

	if(!in) {
		return false;
	}

	ImageSpec spec;
	if(!in->open(filename, spec)) {
		delete in;
		return false;
	}

	metadata.width = spec.width;
	metadata.height = spec.height;
	metadata.depth = spec.depth;

	/* check the main format, and channel formats;
	 * if any take up more than one byte, we'll need a float texture slot */
	if(spec.format.basesize() > 1) {
		metadata.is_float = true;
		metadata.is_linear = true;
	}

	for(size_t channel = 0; channel < spec.channelformats.size(); channel++) {
		if(spec.channelformats[channel].basesize() > 1) {
			metadata.is_float = true;
			metadata.is_linear = true;
		}
	}

	/* check if it's half float */
	if(spec.format == TypeDesc::HALF)
		metadata.is_half = true;

	/* basic color space detection, not great but better than nothing
	 * before we do OpenColorIO integration */
	if(metadata.is_float) {
		string colorspace = spec.get_string_attribute("oiio:ColorSpace");

		metadata.is_linear = !(colorspace == "sRGB" ||
							   colorspace == "GammaCorrected" ||
							   (colorspace == "" &&
								   (strcmp(in->format_name(), "png") == 0 ||
									strcmp(in->format_name(), "tiff") == 0 ||
									strcmp(in->format_name(), "dpx") == 0 ||
									strcmp(in->format_name(), "jpeg2000") == 0)));
	}
	else {
		metadata.is_linear = false;
	}

	/* set type and channels */
	metadata.channels = spec.nchannels;

	if(metadata.is_half) {
		metadata.type = (metadata.channels > 1) ? IMAGE_DATA_TYPE_HALF4 : IMAGE_DATA_TYPE_HALF;
	}
	else if(metadata.is_float) {
		metadata.type = (metadata.channels > 1) ? IMAGE_DATA_TYPE_FLOAT4 : IMAGE_DATA_TYPE_FLOAT;
	}
	else {
		metadata.type = (metadata.channels > 1) ? IMAGE_DATA_TYPE_BYTE4 : IMAGE_DATA_TYPE_BYTE;
	}

	in->close();
	delete in;

	return true;
}
Example #13
0
bool ImageManager::file_load_image(Image *img,
                                   ImageDataType type,
                                   int texture_limit,
                                   device_vector<DeviceType>& tex_img)
{
	const StorageType alpha_one = (FileFormat == TypeDesc::UINT8)? 255 : 1;
	ImageInput *in = NULL;
	int width, height, depth, components;
	if(!file_load_image_generic(img, &in, width, height, depth, components)) {
		return false;
	}
	/* Read RGBA pixels. */
	vector<StorageType> pixels_storage;
	StorageType *pixels;
	const size_t max_size = max(max(width, height), depth);
	if(max_size == 0) {
		/* Don't bother with invalid images. */
		return false;
	}
	if(texture_limit > 0 && max_size > texture_limit) {
		pixels_storage.resize(((size_t)width)*height*depth*4);
		pixels = &pixels_storage[0];
	}
	else {
		thread_scoped_lock device_lock(device_mutex);
		pixels = (StorageType*)tex_img.alloc(width, height, depth);
	}
	if(pixels == NULL) {
		/* Could be that we've run out of memory. */
		return false;
	}
	bool cmyk = false;
	const size_t num_pixels = ((size_t)width) * height * depth;
	if(in) {
		StorageType *readpixels = pixels;
		vector<StorageType> tmppixels;
		if(components > 4) {
			tmppixels.resize(((size_t)width)*height*components);
			readpixels = &tmppixels[0];
		}
		if(depth <= 1) {
			size_t scanlinesize = ((size_t)width)*components*sizeof(StorageType);
			in->read_image(FileFormat,
			               (uchar*)readpixels + (height-1)*scanlinesize,
			               AutoStride,
			               -scanlinesize,
			               AutoStride);
		}
		else {
			in->read_image(FileFormat, (uchar*)readpixels);
		}
		if(components > 4) {
			size_t dimensions = ((size_t)width)*height;
			for(size_t i = dimensions-1, pixel = 0; pixel < dimensions; pixel++, i--) {
				pixels[i*4+3] = tmppixels[i*components+3];
				pixels[i*4+2] = tmppixels[i*components+2];
				pixels[i*4+1] = tmppixels[i*components+1];
				pixels[i*4+0] = tmppixels[i*components+0];
			}
			tmppixels.clear();
		}
		cmyk = strcmp(in->format_name(), "jpeg") == 0 && components == 4;
		in->close();
		delete in;
	}
	else {
		if(FileFormat == TypeDesc::FLOAT) {
			builtin_image_float_pixels_cb(img->filename,
			                              img->builtin_data,
			                              (float*)&pixels[0],
			                              num_pixels * components,
			                              img->builtin_free_cache);
		}
		else if(FileFormat == TypeDesc::UINT8) {
			builtin_image_pixels_cb(img->filename,
			                        img->builtin_data,
			                        (uchar*)&pixels[0],
			                        num_pixels * components,
			                        img->builtin_free_cache);
		}
		else {
			/* TODO(dingto): Support half for ImBuf. */
		}
	}
	/* Check if we actually have a float4 slot, in case components == 1,
	 * but device doesn't support single channel textures.
	 */
	bool is_rgba = (type == IMAGE_DATA_TYPE_FLOAT4 ||
	                type == IMAGE_DATA_TYPE_HALF4 ||
	                type == IMAGE_DATA_TYPE_BYTE4);
	if(is_rgba) {
		if(cmyk) {
			/* CMYK */
			for(size_t i = num_pixels-1, pixel = 0; pixel < num_pixels; pixel++, i--) {
				pixels[i*4+2] = (pixels[i*4+2]*pixels[i*4+3])/255;
				pixels[i*4+1] = (pixels[i*4+1]*pixels[i*4+3])/255;
				pixels[i*4+0] = (pixels[i*4+0]*pixels[i*4+3])/255;
				pixels[i*4+3] = alpha_one;
			}
		}
		else if(components == 2) {
			/* grayscale + alpha */
			for(size_t i = num_pixels-1, pixel = 0; pixel < num_pixels; pixel++, i--) {
				pixels[i*4+3] = pixels[i*2+1];
				pixels[i*4+2] = pixels[i*2+0];
				pixels[i*4+1] = pixels[i*2+0];
				pixels[i*4+0] = pixels[i*2+0];
			}
		}
		else if(components == 3) {
			/* RGB */
			for(size_t i = num_pixels-1, pixel = 0; pixel < num_pixels; pixel++, i--) {
				pixels[i*4+3] = alpha_one;
				pixels[i*4+2] = pixels[i*3+2];
				pixels[i*4+1] = pixels[i*3+1];
				pixels[i*4+0] = pixels[i*3+0];
			}
		}
		else if(components == 1) {
			/* grayscale */
			for(size_t i = num_pixels-1, pixel = 0; pixel < num_pixels; pixel++, i--) {
				pixels[i*4+3] = alpha_one;
				pixels[i*4+2] = pixels[i];
				pixels[i*4+1] = pixels[i];
				pixels[i*4+0] = pixels[i];
			}
		}
		if(img->use_alpha == false) {
			for(size_t i = num_pixels-1, pixel = 0; pixel < num_pixels; pixel++, i--) {
				pixels[i*4+3] = alpha_one;
			}
		}
	}
	/* Make sure we don't have buggy values. */
	if(FileFormat == TypeDesc::FLOAT) {
		/* For RGBA buffers we put all channels to 0 if either of them is not
		 * finite. This way we avoid possible artifacts caused by fully changed
		 * hue.
		 */
		if(is_rgba) {
			for(size_t i = 0; i < num_pixels; i += 4) {
				StorageType *pixel = &pixels[i*4];
				if(!isfinite(pixel[0]) ||
				   !isfinite(pixel[1]) ||
				   !isfinite(pixel[2]) ||
				   !isfinite(pixel[3]))
				{
					pixel[0] = 0;
					pixel[1] = 0;
					pixel[2] = 0;
					pixel[3] = 0;
				}
			}
		}
		else {
			for(size_t i = 0; i < num_pixels; ++i) {
				StorageType *pixel = &pixels[i];
				if(!isfinite(pixel[0])) {
					pixel[0] = 0;
				}
			}
		}
	}
	/* Scale image down if needed. */
	if(pixels_storage.size() > 0) {
		float scale_factor = 1.0f;
		while(max_size * scale_factor > texture_limit) {
			scale_factor *= 0.5f;
		}
		VLOG(1) << "Scaling image " << img->filename
		        << " by a factor of " << scale_factor << ".";
		vector<StorageType> scaled_pixels;
		size_t scaled_width, scaled_height, scaled_depth;
		util_image_resize_pixels(pixels_storage,
		                         width, height, depth,
		                         is_rgba ? 4 : 1,
		                         scale_factor,
		                         &scaled_pixels,
		                         &scaled_width, &scaled_height, &scaled_depth);

		StorageType *texture_pixels;

		{
			thread_scoped_lock device_lock(device_mutex);
			texture_pixels = (StorageType*)tex_img.alloc(scaled_width,
			                                             scaled_height,
			                                             scaled_depth);
		}

		memcpy(texture_pixels,
		       &scaled_pixels[0],
		       scaled_pixels.size() * sizeof(StorageType));
	}
	return true;
}
Example #14
0
bool ImageManager::file_load_image(Image *img, device_vector<uchar4>& tex_img)
{
	if(img->filename == "")
		return false;

  fprintf(stderr, "image input disabled\n");
#if 0

	/* load image from file through OIIO */
	ImageInput *in = ImageInput::create(img->filename);

	if(!in)
		return false;

	ImageSpec spec;

	if(!in->open(img->filename, spec)) {
		delete in;
		return false;
	}

	/* we only handle certain number of components */
	int width = spec.width;
	int height = spec.height;
	int components = spec.nchannels;

	if(!(components == 1 || components == 3 || components == 4)) {
		in->close();
		delete in;
		return false;
	}

	/* read RGBA pixels */
	uchar *pixels = (uchar*)tex_img.resize(width, height);
	int scanlinesize = width*components*sizeof(uchar);

	in->read_image(TypeDesc::UINT8,
		(uchar*)pixels + (height-1)*scanlinesize,
		AutoStride,
		-scanlinesize,
		AutoStride);

	in->close();
	delete in;

	if(components == 3) {
		for(int i = width*height-1; i >= 0; i--) {
			pixels[i*4+3] = 255;
			pixels[i*4+2] = pixels[i*3+2];
			pixels[i*4+1] = pixels[i*3+1];
			pixels[i*4+0] = pixels[i*3+0];
		}
	}
	else if(components == 1) {
		for(int i = width*height-1; i >= 0; i--) {
			pixels[i*4+3] = 255;
			pixels[i*4+2] = pixels[i];
			pixels[i*4+1] = pixels[i];
			pixels[i*4+0] = pixels[i];
		}
	}

	return true;
#endif 
	return false;
}
Example #15
0
bool ImageManager::file_load_half_image(Image *img, ImageDataType type, device_vector<T>& tex_img)
{
	ImageInput *in = NULL;
	int width, height, depth, components;

	if(!file_load_image_generic(img, &in, width, height, depth, components))
		return false;

	/* read RGBA pixels */
	half *pixels = (half*)tex_img.resize(width, height, depth);
	if(pixels == NULL) {
		return false;
	}

	if(in) {
		half *readpixels = pixels;
		vector<half> tmppixels;

		if(components > 4) {
			tmppixels.resize(((size_t)width)*height*components);
			readpixels = &tmppixels[0];
		}

		if(depth <= 1) {
			size_t scanlinesize = ((size_t)width)*components*sizeof(half);
			in->read_image(TypeDesc::HALF,
			               (uchar*)readpixels + (height-1)*scanlinesize,
			               AutoStride,
			               -scanlinesize,
			               AutoStride);
		}
		else {
			in->read_image(TypeDesc::HALF, (uchar*)readpixels);
		}

		if(components > 4) {
			size_t dimensions = ((size_t)width)*height;
			for(size_t i = dimensions-1, pixel = 0; pixel < dimensions; pixel++, i--) {
				pixels[i*4+3] = tmppixels[i*components+3];
				pixels[i*4+2] = tmppixels[i*components+2];
				pixels[i*4+1] = tmppixels[i*components+1];
				pixels[i*4+0] = tmppixels[i*components+0];
			}

			tmppixels.clear();
		}

		in->close();
		delete in;
	}
#if 0
	/* TODO(dingto): Support half for ImBuf. */
	else {
		builtin_image_float_pixels_cb(img->filename, img->builtin_data, pixels);
	}
#endif

	/* Check if we actually have a half4 slot, in case components == 1, but device
	 * doesn't support single channel textures. */
	if(type == IMAGE_DATA_TYPE_HALF4) {
		size_t num_pixels = ((size_t)width) * height * depth;
		if(components == 2) {
			/* grayscale + alpha */
			for(size_t i = num_pixels-1, pixel = 0; pixel < num_pixels; pixel++, i--) {
				pixels[i*4+3] = pixels[i*2+1];
				pixels[i*4+2] = pixels[i*2+0];
				pixels[i*4+1] = pixels[i*2+0];
				pixels[i*4+0] = pixels[i*2+0];
			}
		}
		else if(components == 3) {
			/* RGB */
			for(size_t i = num_pixels-1, pixel = 0; pixel < num_pixels; pixel++, i--) {
				pixels[i*4+3] = 1.0f;
				pixels[i*4+2] = pixels[i*3+2];
				pixels[i*4+1] = pixels[i*3+1];
				pixels[i*4+0] = pixels[i*3+0];
			}
		}
		else if(components == 1) {
			/* grayscale */
			for(size_t i = num_pixels-1, pixel = 0; pixel < num_pixels; pixel++, i--) {
				pixels[i*4+3] = 1.0f;
				pixels[i*4+2] = pixels[i];
				pixels[i*4+1] = pixels[i];
				pixels[i*4+0] = pixels[i];
			}
		}

		if(img->use_alpha == false) {
			for(size_t i = num_pixels-1, pixel = 0; pixel < num_pixels; pixel++, i--) {
				pixels[i*4+3] = 1.0f;
			}
		}
	}

	return true;
}
Example #16
0
static void LoadTexture(std::string const& filename, Scene::Texture& texture, std::vector<std::unique_ptr<char[]> >& data)
{
	OIIO_NAMESPACE_USING

	ImageInput* input = ImageInput::open(filename);

	if (!input)
	{
		throw std::runtime_error("Can't load " + filename + " image");
	}

	ImageSpec const& spec = input->spec();

	texture.w = spec.width;
	texture.h = spec.height;
	texture.d = spec.depth;
	texture.fmt = GetTextureForemat(spec);

	// Save old size for reading offset
	texture.dataoffset = (int)data.size();

	if (texture.fmt == Scene::RGBA8)
	{
		texture.size = spec.width * spec.height * spec.depth * 4;

		// Resize storage
		std::unique_ptr<char[]> texturedata(new char[spec.width * spec.height * spec.depth * 4]);

		// Read data to storage
		input->read_image(TypeDesc::UINT8, texturedata.get(), sizeof(char) * 4);

		// Close handle
		input->close();

		// Add to texture pool
		data.push_back(std::move(texturedata));
	}
	else if (texture.fmt == Scene::RGBA16)
	{
		texture.size = spec.width * spec.height * spec.depth * sizeof(float) * 2;

		// Resize storage
		std::unique_ptr<char[]> texturedata(new char[spec.width * spec.height * spec.depth * sizeof(float) * 2]);

		// Read data to storage
		input->read_image(TypeDesc::HALF, texturedata.get(), sizeof(float) * 2);

		// Close handle
		input->close();

		// Add to texture pool
		data.push_back(std::move(texturedata));
	}
	else
	{
		texture.size = spec.width * spec.height * spec.depth * sizeof(float3);

		// Resize storage
		std::unique_ptr<char[]> texturedata(new char[spec.width * spec.height * spec.depth * sizeof(float3)]);

		// Read data to storage
		input->read_image(TypeDesc::FLOAT, texturedata.get(), sizeof(float3));

		// Close handle
		input->close();

		// Add to texture pool
		data.push_back(std::move(texturedata));
	}

	// Cleanup
	delete input;
}
Example #17
0
bool
OiioTool::print_info (Oiiotool &ot,
                      const std::string &filename,
                      const print_info_options &opt,
                      long long &totalsize,
                      std::string &error)
{
    using Strutil::format;
    error.clear();
    ImageSpec *config = ot.input_config_set ? &ot.input_config : NULL;
    ImageInput *input = ImageInput::open (filename.c_str(), config);
    if (! input) {
        error = geterror();
        if (error.empty())
            error = Strutil::format ("Could not open \"%s\"", filename);
        return false;
    }
    ImageSpec spec = input->spec();

    ImageSpec::SerialFormat serformat = ImageSpec::SerialText;
    if (Strutil::iequals (opt.infoformat, "xml"))
        serformat = ImageSpec::SerialXML;
    ImageSpec::SerialVerbose verbose = opt.verbose ? ImageSpec::SerialDetailedHuman : ImageSpec::SerialBrief;

    boost::regex field_re;
    boost::regex field_exclude_re;
    if (! opt.metamatch.empty()) {
        try {
            field_re.assign (opt.metamatch,
                         boost::regex::extended | boost::regex_constants::icase);
        } catch (const std::exception &e) {
            error = Strutil::format ("Regex error '%s' on metamatch regex \"%s\"",
                                     e.what(), opt.metamatch);
            return false;
        }
    }
    if (! opt.nometamatch.empty()) {
        try {
            field_exclude_re.assign (opt.nometamatch,
                         boost::regex::extended | boost::regex_constants::icase);
        } catch (const std::exception &e) {
            error = Strutil::format ("Regex error '%s' on metamatch regex \"%s\"",
                                     e.what(), opt.nometamatch);
            return false;
        }
    }

    // checking how many subimages and mipmap levels are stored in the file
    std::vector<int> num_of_miplevels;
    int num_of_subimages;
    for (num_of_subimages = 0; input->seek_subimage (num_of_subimages, 0, spec); ++num_of_subimages) {
        int nmip = 1;
        while (input->seek_subimage (num_of_subimages, nmip, spec))
            ++nmip;
        num_of_miplevels.push_back (nmip);
    }

    for (int current_subimage = 0; current_subimage < num_of_subimages; ++current_subimage) {
        if ( ! input->seek_subimage (current_subimage, 0, spec) )
            break;
        print_info_subimage (ot, current_subimage, num_of_subimages,
                             num_of_miplevels[current_subimage],
                             spec, input, filename, opt,
                             field_re, field_exclude_re, serformat, verbose);
        // if the '-a' flag is not set we print info
        // about first subimage only
        if ( ! opt.subimages)
            break;
    }

    input->close ();
    delete input;
    return true;
}
Example #18
0
static bool
convert_file (const std::string &in_filename, const std::string &out_filename)
{
    if (noclobber && Filesystem::exists(out_filename)) {
        std::cerr << "iconvert ERROR: Output file already exists \""
                  << out_filename << "\"\n";
        return false;
    }

    if (verbose)
        std::cout << "Converting " << in_filename << " to " << out_filename << "\n";

    std::string tempname = out_filename;
    if (tempname == in_filename) {
        tempname = out_filename + ".tmp"
                    + Filesystem::extension (out_filename);
    }

    // Find an ImageIO plugin that can open the input file, and open it.
    ImageInput *in = ImageInput::open (in_filename.c_str());
    if (! in) {
        std::string err = geterror();
        std::cerr << "iconvert ERROR: " 
                  << (err.length() ? err : Strutil::format("Could not open \"%s\"", in_filename))
                  << "\n";
        delete in;
        return false;
    }
    ImageSpec inspec = in->spec();
    std::string metadatatime = inspec.get_string_attribute ("DateTime");

    // Find an ImageIO plugin that can open the output file, and open it
    ImageOutput *out = ImageOutput::create (tempname.c_str());
    if (! out) {
        std::cerr 
            << "iconvert ERROR: Could not find an ImageIO plugin to write \"" 
            << out_filename << "\" :" << geterror() << "\n";
        delete in;
        return false;
    }

    // In order to deal with formats that support subimages, but not
    // subimage appending, we gather them all first.
    std::vector<ImageSpec> subimagespecs;
    if (out->supports("multiimage") && !out->supports("appendsubimage")) {
        ImageCache *imagecache = ImageCache::create ();
        int nsubimages = 0;
        ustring ufilename (in_filename);
        imagecache->get_image_info (ufilename, 0, 0, ustring("subimages"),
                                    TypeDesc::TypeInt, &nsubimages);
        if (nsubimages > 1) {
            subimagespecs.resize (nsubimages);
            for (int i = 0;  i < nsubimages;  ++i) {
                ImageSpec inspec = *imagecache->imagespec (ufilename, i, 0,
                                                           true /*native*/);
                subimagespecs[i] = inspec;
                adjust_spec (in, out, inspec, subimagespecs[i]);
            }
        }
        ImageCache::destroy (imagecache);
    }

    bool ok = true;
    bool mip_to_subimage_warning = false;
    for (int subimage = 0;
           ok && in->seek_subimage(subimage,0,inspec);
           ++subimage) {

        if (subimage > 0 &&  !out->supports ("multiimage")) {
            std::cerr << "iconvert WARNING: " << out->format_name()
                      << " does not support multiple subimages.\n";
            std::cerr << "\tOnly the first subimage has been copied.\n";
            break;  // we're done
        }

        int miplevel = 0;
        do {
            // Copy the spec, with possible change in format
            ImageSpec outspec = inspec;
            bool nocopy = adjust_spec (in, out, inspec, outspec);
        
            if (miplevel > 0) {
                // Moving to next MIP level
                ImageOutput::OpenMode mode;
                if (out->supports ("mipmap"))
                    mode = ImageOutput::AppendMIPLevel;
                else if (out->supports ("multiimage") &&
                         out->supports ("appendsubimage")) {
                    mode = ImageOutput::AppendSubimage; // use if we must
                    if (! mip_to_subimage_warning
                        && strcmp(out->format_name(),"tiff")) {
                        std::cerr << "iconvert WARNING: " << out->format_name()
                                  << " does not support MIPmaps.\n";
                        std::cerr << "\tStoring the MIPmap levels in subimages.\n";
                    }
                    mip_to_subimage_warning = true;
                } else {
                    std::cerr << "iconvert WARNING: " << out->format_name()
                              << " does not support MIPmaps.\n";
                    std::cerr << "\tOnly the first level has been copied.\n";
                    break;  // on to the next subimage
                }
                ok = out->open (tempname.c_str(), outspec, mode);
            } else if (subimage > 0) {
                // Moving to next subimage
                ok = out->open (tempname.c_str(), outspec,
                                ImageOutput::AppendSubimage);
            } else {
                // First time opening
                if (subimagespecs.size())
                    ok = out->open (tempname.c_str(), int(subimagespecs.size()),
                                    &subimagespecs[0]);
                else
                    ok = out->open (tempname.c_str(), outspec, ImageOutput::Create);
            }
            if (! ok) {
                std::string err = out->geterror();
                std::cerr << "iconvert ERROR: " 
                          << (err.length() ? err : Strutil::format("Could not open \"%s\"", out_filename))
                          << "\n";
                ok = false;
                break;
            }

            if (! nocopy) {
                ok = out->copy_image (in);
                if (! ok)
                    std::cerr << "iconvert ERROR copying \"" << in_filename 
                              << "\" to \"" << out_filename << "\" :\n\t" 
                              << out->geterror() << "\n";
            } else {
                // Need to do it by hand for some reason.  Future expansion in which
                // only a subset of channels are copied, or some such.
                std::vector<char> pixels ((size_t)outspec.image_bytes(true));
                ok = in->read_image (outspec.format, &pixels[0]);
                if (! ok) {
                    std::cerr << "iconvert ERROR reading \"" << in_filename 
                              << "\" : " << in->geterror() << "\n";
                } else {
                    ok = out->write_image (outspec.format, &pixels[0]);
                    if (! ok)
                        std::cerr << "iconvert ERROR writing \"" << out_filename 
                                  << "\" : " << out->geterror() << "\n";
                }
            }
        
            ++miplevel;
        } while (ok && in->seek_subimage(subimage,miplevel,inspec));
    }

    out->close ();
    delete out;
    in->close ();
    delete in;

    // Figure out a time for the input file -- either one supplied by
    // the metadata, or the actual time stamp of the input file.
    std::time_t in_time;
    if (metadatatime.empty() ||
           ! DateTime_to_time_t (metadatatime.c_str(), in_time))
        in_time = Filesystem::last_write_time (in_filename);

    if (out_filename != tempname) {
        if (ok) {
            Filesystem::remove (out_filename);
            Filesystem::rename (tempname, out_filename);
        }
        else
            Filesystem::remove (tempname);
    }

    // If user requested, try to adjust the file's modification time to
    // the creation time indicated by the file's DateTime metadata.
    if (ok && adjust_time)
        Filesystem::last_write_time (out_filename, in_time);

    return ok;
}
Example #19
0
struct ImBuf *imb_load_photoshop(const char *filename, int flags, char colorspace[IM_MAX_SPACE])
{
	ImageInput *in = NULL;
	struct ImBuf *ibuf = NULL;
	int width, height, components;
	bool is_float, is_alpha;
	TypeDesc typedesc;
	int basesize;
	char file_colorspace[IM_MAX_SPACE];

	/* load image from file through OIIO */
	if (imb_is_a_photoshop(filename) == 0) return (NULL);

	colorspace_set_default_role(colorspace, IM_MAX_SPACE, COLOR_ROLE_DEFAULT_BYTE);

	in = ImageInput::create(filename);
	if (!in) {
		std::cerr << __func__ << ": ImageInput::create() failed:" << std::endl
		          << OpenImageIO::geterror() << std::endl;
		return NULL;
	}

	ImageSpec spec, config;
	config.attribute("oiio:UnassociatedAlpha", (int) 1);

	if (!in->open(filename, spec, config)) {
		std::cerr << __func__ << ": ImageInput::open() failed:" << std::endl
		          << in->geterror() << std::endl;
		delete in;
		return NULL;
	}

	string ics = spec.get_string_attribute("oiio:ColorSpace");
	BLI_strncpy(file_colorspace, ics.c_str(), IM_MAX_SPACE);

	/* only use colorspaces exis */
	if (colormanage_colorspace_get_named(file_colorspace))
		strcpy(colorspace, file_colorspace);
	else
		std::cerr << __func__ << ": The embed colorspace (\"" << file_colorspace
		          << "\") not supported in existent OCIO configuration file. Fallback "
		          << "to system default colorspace (\"" << colorspace << "\")." << std::endl;

	width = spec.width;
	height = spec.height;
	components = spec.nchannels;
	is_alpha = spec.alpha_channel != -1;
	basesize = spec.format.basesize();
	is_float = basesize > 1;

	/* we only handle certain number of components */
	if (!(components >= 1 && components <= 4)) {
		if (in) {
			in->close();
			delete in;
		}
		return NULL;
	}

	if (is_float)
		ibuf = imb_oiio_load_image_float(in, width, height, components, flags, is_alpha);
	else
		ibuf = imb_oiio_load_image(in, width, height, components, flags, is_alpha);

	if (in) {
		in->close();
		delete in;
	}

	if (!ibuf)
		return NULL;

	/* ImBuf always needs 4 channels */
	ibuf->ftype = IMB_FTYPE_PSD;
	ibuf->channels = 4;
	ibuf->planes = (3 + (is_alpha ? 1 : 0)) * 4 << basesize;

	try
	{
		return ibuf;
	}
	catch (const std::exception &exc)
	{
		std::cerr << exc.what() << std::endl;
		if (ibuf) IMB_freeImBuf(ibuf);

		return NULL;
	}
}
Example #20
0
bool ImageManager::file_load_float_image(Image *img, device_vector<float4>& tex_img)
{
	if(img->filename == "")
		return false;

	/* load image from file through OIIO */
	ImageInput *in = ImageInput::create(img->filename);

	if(!in)
		return false;

	ImageSpec spec;

	if(!in->open(img->filename, spec)) {
		delete in;
		return false;
	}

	/* we only handle certain number of components */
	int width = spec.width;
	int height = spec.height;
	int components = spec.nchannels;

	if(!(components == 1 || components == 3 || components == 4)) {
		in->close();
		delete in;
		return false;
	}

	printf("loading float image: '%s' %dx%d\n", img->filename.c_str(), width, height);

	/* read RGBA pixels */
	float *pixels = (float*)tex_img.resize(width, height);
	int scanlinesize = width*components*sizeof(float);

	in->read_image(TypeDesc::FLOAT,
		(uchar*)pixels + (height-1)*scanlinesize,
		AutoStride,
		-scanlinesize,
		AutoStride);

	in->close();
	delete in;

	if(components == 3) {
		for(int i = width*height-1; i >= 0; i--) {
			pixels[i*4+3] = 1.0f;
			pixels[i*4+2] = pixels[i*3+2];
			pixels[i*4+1] = pixels[i*3+1];
			pixels[i*4+0] = pixels[i*3+0];
		}
	}
	else if(components == 1) {
		for(int i = width*height-1; i >= 0; i--) {
			pixels[i*4+3] = 1.0f;
			pixels[i*4+2] = pixels[i];
			pixels[i*4+1] = pixels[i];
			pixels[i*4+0] = pixels[i];
		}
	}

	return true;
}
Example #21
0
ImageManager::ImageDataType ImageManager::get_image_metadata(const string& filename,
                                                             void *builtin_data,
                                                             bool& is_linear)
{
	bool is_float = false, is_half = false;
	is_linear = false;
	int channels = 4;

	if(builtin_data) {
		if(builtin_image_info_cb) {
			int width, height, depth;
			builtin_image_info_cb(filename, builtin_data, is_float, width, height, depth, channels);
		}

		if(is_float) {
			is_linear = true;
			return (channels > 1) ? IMAGE_DATA_TYPE_FLOAT4 : IMAGE_DATA_TYPE_FLOAT;
		}
		else {
			return (channels > 1) ? IMAGE_DATA_TYPE_BYTE4 : IMAGE_DATA_TYPE_BYTE;
		}
	}

	ImageInput *in = ImageInput::create(filename);

	if(in) {
		ImageSpec spec;

		if(in->open(filename, spec)) {
			/* check the main format, and channel formats;
			 * if any take up more than one byte, we'll need a float texture slot */
			if(spec.format.basesize() > 1) {
				is_float = true;
				is_linear = true;
			}

			for(size_t channel = 0; channel < spec.channelformats.size(); channel++) {
				if(spec.channelformats[channel].basesize() > 1) {
					is_float = true;
					is_linear = true;
				}
			}

			/* check if it's half float */
			if(spec.format == TypeDesc::HALF)
				is_half = true;

			channels = spec.nchannels;

			/* basic color space detection, not great but better than nothing
			 * before we do OpenColorIO integration */
			if(is_float) {
				string colorspace = spec.get_string_attribute("oiio:ColorSpace");

				is_linear = !(colorspace == "sRGB" ||
				              colorspace == "GammaCorrected" ||
				              (colorspace == "" &&
				                  (strcmp(in->format_name(), "png") == 0 ||
				                   strcmp(in->format_name(), "tiff") == 0 ||
				                   strcmp(in->format_name(), "dpx") == 0 ||
				                   strcmp(in->format_name(), "jpeg2000") == 0)));
			}
			else {
				is_linear = false;
			}

			in->close();
		}

		delete in;
	}

	if(is_half) {
		return (channels > 1) ? IMAGE_DATA_TYPE_HALF4 : IMAGE_DATA_TYPE_HALF;
	}
	else if(is_float) {
		return (channels > 1) ? IMAGE_DATA_TYPE_FLOAT4 : IMAGE_DATA_TYPE_FLOAT;
	}
	else {
		return (channels > 1) ? IMAGE_DATA_TYPE_BYTE4 : IMAGE_DATA_TYPE_BYTE;
	}
}
Example #22
0
ImageInput *
ImageInput::create (const std::string &filename, 
                    bool do_open,
                    const std::string &plugin_searchpath)
{
    if (filename.empty()) { // Can't even guess if no filename given
        pvt::error ("ImageInput::create() called with no filename");
        return NULL;
    }

    // Extract the file extension from the filename (without the leading dot)
    std::string format = Filesystem::extension (filename, false);
    if (format.empty()) {
        // If the file had no extension, maybe it was itself the format name
        format = filename;
    }

    ImageInput::Creator create_function = NULL;
    { // scope the lock:
        recursive_lock_guard lock (imageio_mutex);  // Ensure thread safety

        // See if it's already in the table.  If not, scan all plugins we can
        // find to populate the table.
        Strutil::to_lower (format);
        InputPluginMap::const_iterator found = input_formats.find (format);
        if (found == input_formats.end()) {
            catalog_all_plugins (plugin_searchpath.size() ? plugin_searchpath
                                 : pvt::plugin_searchpath.string());
            found = input_formats.find (format);
        }
        if (found != input_formats.end())
            create_function = found->second;
    }

    // Remember which prototypes we've already tried, so we don't double dip.
    std::vector<ImageInput::Creator> formats_tried;

    std::string specific_error;
    if (create_function) {
        if (filename != format) {
            // If given a full filename, double-check that our guess
            // based on the extension actually works.  You never know
            // when somebody will have an incorrectly-named file, let's
            // deal with it robustly.
            formats_tried.push_back (create_function);
            ImageInput *in = (ImageInput *)create_function();
            if (! do_open && in && in->valid_file(filename)) {
                // Special case: we don't need to return the file
                // already opened, and this ImageInput says that the
                // file is the right type.
                return in;
            }
            ImageSpec tmpspec;
            bool ok = in && in->open (filename, tmpspec);
            if (ok) {
                // It worked
                if (! do_open)
                    in->close ();
                return in;
            } else {
                // Oops, it failed.  Apparently, this file can't be
                // opened with this II.  Clear create_function to force
                // the code below to check every plugin we know.
                create_function = NULL;
                if (in)
                    specific_error = in->geterror();
            }
            delete in;
        }
    }

    if (! create_function) {
        // If a plugin can't be found that was explicitly designated for
        // this extension, then just try every one we find and see if
        // any will open the file.  Pass it a configuration request that
        // includes a "nowait" option so that it returns immediately if
        // it's a plugin that might wait for an event, like a socket that
        // doesn't yet exist).
        ImageSpec config;
        config.attribute ("nowait", (int)1);
        recursive_lock_guard lock (imageio_mutex);  // Ensure thread safety
        for (InputPluginMap::const_iterator plugin = input_formats.begin();
             plugin != input_formats.end(); ++plugin)
        {
            // If we already tried this create function, don't do it again
            if (std::find (formats_tried.begin(), formats_tried.end(),
                           plugin->second) != formats_tried.end())
                continue;
            formats_tried.push_back (plugin->second);  // remember

            ImageSpec tmpspec;
            ImageInput *in = NULL;
            try {
                in = plugin->second();
            } catch (...) {
                // Safety in case the ctr throws an exception
            }
            if (! in)
                continue;
            if (! do_open && ! in->valid_file(filename)) {
                // Since we didn't need to open it, we just checked whether
                // it was a valid file, and it's not.  Try the next one.
                delete in;
                continue;
            }
            // We either need to open it, or we already know it appears
            // to be a file of the right type.
            bool ok = in->open(filename, tmpspec, config);
            if (ok) {
                if (! do_open)
                    in->close ();
                return in;
            }
            delete in;
        }
    }

    if (create_function == NULL) {
        recursive_lock_guard lock (imageio_mutex);  // Ensure thread safety
        if (input_formats.empty()) {
            // This error is so fundamental, we echo it to stderr in
            // case the app is too dumb to do so.
            const char *msg = "ImageInput::create() could not find any ImageInput plugins!\n"
                          "    Perhaps you need to set OIIO_LIBRARY_PATH.\n";
            fprintf (stderr, "%s", msg);
            pvt::error ("%s", msg);
        }
        else if (! specific_error.empty()) {
            // Pass along any specific error message we got from our
            // best guess of the format.
            pvt::error ("%s", specific_error);
        }
        else if (Filesystem::exists (filename))
            pvt::error ("OpenImageIO could not find a format reader for \"%s\". "
                        "Is it a file format that OpenImageIO doesn't know about?\n",
                         filename.c_str());
        else
            pvt::error ("Image \"%s\" does not exist. Also, it is not the name of an image format that OpenImageIO recognizes.\n",
                         filename.c_str());
        return NULL;
    }

    return (ImageInput *) create_function();
}
Example #23
0
bool ImageManager::file_load_float_image(Image *img, ImageDataType type, device_vector<T>& tex_img)
{
	ImageInput *in = NULL;
	int width, height, depth, components;

	if(!file_load_image_generic(img, &in, width, height, depth, components))
		return false;

	/* read RGBA pixels */
	float *pixels = (float*)tex_img.resize(width, height, depth);
	if(pixels == NULL) {
		return false;
	}
	bool cmyk = false;

	if(in) {
		float *readpixels = pixels;
		vector<float> tmppixels;

		if(components > 4) {
			tmppixels.resize(((size_t)width)*height*components);
			readpixels = &tmppixels[0];
		}

		if(depth <= 1) {
			size_t scanlinesize = ((size_t)width)*components*sizeof(float);
			in->read_image(TypeDesc::FLOAT,
			               (uchar*)readpixels + (height-1)*scanlinesize,
			               AutoStride,
			               -scanlinesize,
			               AutoStride);
		}
		else {
			in->read_image(TypeDesc::FLOAT, (uchar*)readpixels);
		}

		if(components > 4) {
			size_t dimensions = ((size_t)width)*height;
			for(size_t i = dimensions-1, pixel = 0; pixel < dimensions; pixel++, i--) {
				pixels[i*4+3] = tmppixels[i*components+3];
				pixels[i*4+2] = tmppixels[i*components+2];
				pixels[i*4+1] = tmppixels[i*components+1];
				pixels[i*4+0] = tmppixels[i*components+0];
			}

			tmppixels.clear();
		}

		cmyk = strcmp(in->format_name(), "jpeg") == 0 && components == 4;

		in->close();
		delete in;
	}
	else {
		builtin_image_float_pixels_cb(img->filename, img->builtin_data, pixels);
	}

	/* Check if we actually have a float4 slot, in case components == 1, but device
	 * doesn't support single channel textures. */
	if(type == IMAGE_DATA_TYPE_FLOAT4) {
		size_t num_pixels = ((size_t)width) * height * depth;
		if(cmyk) {
			/* CMYK */
			for(size_t i = num_pixels-1, pixel = 0; pixel < num_pixels; pixel++, i--) {
				pixels[i*4+3] = 255;
				pixels[i*4+2] = (pixels[i*4+2]*pixels[i*4+3])/255;
				pixels[i*4+1] = (pixels[i*4+1]*pixels[i*4+3])/255;
				pixels[i*4+0] = (pixels[i*4+0]*pixels[i*4+3])/255;
			}
		}
		else if(components == 2) {
			/* grayscale + alpha */
			for(size_t i = num_pixels-1, pixel = 0; pixel < num_pixels; pixel++, i--) {
				pixels[i*4+3] = pixels[i*2+1];
				pixels[i*4+2] = pixels[i*2+0];
				pixels[i*4+1] = pixels[i*2+0];
				pixels[i*4+0] = pixels[i*2+0];
			}
		}
		else if(components == 3) {
			/* RGB */
			for(size_t i = num_pixels-1, pixel = 0; pixel < num_pixels; pixel++, i--) {
				pixels[i*4+3] = 1.0f;
				pixels[i*4+2] = pixels[i*3+2];
				pixels[i*4+1] = pixels[i*3+1];
				pixels[i*4+0] = pixels[i*3+0];
			}
		}
		else if(components == 1) {
			/* grayscale */
			for(size_t i = num_pixels-1, pixel = 0; pixel < num_pixels; pixel++, i--) {
				pixels[i*4+3] = 1.0f;
				pixels[i*4+2] = pixels[i];
				pixels[i*4+1] = pixels[i];
				pixels[i*4+0] = pixels[i];
			}
		}

		if(img->use_alpha == false) {
			for(size_t i = num_pixels-1, pixel = 0; pixel < num_pixels; pixel++, i--) {
				pixels[i*4+3] = 1.0f;
			}
		}
	}

	return true;
}