예제 #1
0
ImageStat PSDDecoder::DecodeImg(Dib& bmp, CSize& img_size, bool resize, COLORREF rgb_back/*= RGB(255,255,255)*/)
{
	FileStream ifs;
	if (!ifs.Open(file_path_.c_str()))
		return IS_OPEN_ERR;

	if (!psd_.OpenHeader(ifs))
		return IS_FMT_NOT_SUPPORTED;

	if (!psd_.IsSupported())
		return IS_FMT_NOT_SUPPORTED;

	if (!psd_.PrepareReading(ifs, CalcReductionFactor(img_size, false)))
		return IS_FMT_NOT_SUPPORTED;

	// image may be reduced in size
	CSize size= psd_.GetResized();
	bmp.Create(size.cx, size.cy, 24);

	SetTotalLines(psd_.GetHeight());

	if (!LinesDecoded(0, false))
		return IS_DECODING_CANCELLED;

	while (psd_.GetScanLine() < psd_.GetHeight())
	{
		psd_.ReadNextLine(ifs, bmp, 0);

		if (IsICCEnabled())
			ApplyICC(bmp.LineBuffer(psd_.GetScanLine() - 1), bmp.GetWidth(), bmp.GetColorComponents());

		int scan_line= psd_.GetScanLine();

		// report progress
		if (!LinesDecoded(scan_line, scan_line == psd_.GetHeight()))
			return IS_DECODING_CANCELLED;
	}

	if (resize)
		bmp.ResizeToFit(img_size, Dib::RESIZE_CUBIC);

	return IS_OK;
}
예제 #2
0
BOOL RenderWindow::InitGL(void)
{
	Window::InitGL();
	if(!image.LoadFromFile("edin01.bmp"))
	{
		MessageBox(NULL, "edin01.bmp 파일을 불러올 수 없습니다", "오류", MB_OK);
		return FALSE;
	}

	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	glTexImage2D(GL_TEXTURE_2D, 0, 3, image.GetWidth(), image.GetHeight(), 0,
		GL_BGR_EXT, GL_UNSIGNED_BYTE, image.GetRawData());
	glEnable(GL_TEXTURE_2D);

	glFrontFace(GL_CCW);
	glEnable(GL_CULL_FACE);

	glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
	return TRUE;
}
예제 #3
0
void ImageProcessorDlg::Impl::test(ViewPane& view)
{
#if 0
	CImageDecoderPtr d= photos_[0]->GetDecoder();

	Dib bmp;
	CSize size(500,500);
	if (d->DecodeImg(bmp, size, false) != IS_OK)
		return;

	size = CSize(bmp.GetWidth(), bmp.GetHeight());

	ExceptionInfo exc;

	GetExceptionInfo(&exc);

	Image* img= ConstituteImage(bmp.GetWidth(), bmp.GetHeight(), "RGB", CharPixel, bmp.GetBuffer(), &exc);

	if (img)
	{
		double radius= 10.0;
		double sigma= 1.0;
		double amount= 1.0;
		double threshold= 0.01;

	//	Image* sharp= UnsharpMaskImage(img, radius, sigma, amount, threshold, &exc);
		int w= size.cy * 16 / 9;
		Image* sharp= LiquidRescaleImage(img, w, size.cy, 1.0, 0.0, &exc);

		if (sharp)
		{
			//ImageInfo ii;
			//GetImageInfo(&ii);
			//strcpy(sharp->filename, "c:\\sharp.img");
			size.cx = sharp->columns;
			size.cy = sharp->rows;

			const PixelPacket* pix= AcquireImagePixels(sharp, 0, 0, size.cx, size.cy, &exc);

			Dib b(size.cx, size.cy, 24);
			for (int y= size.cy - 1; y >= 0; --y)
			{
				BYTE* line= b.LineBuffer(y);
				for (int x= 0; x < size.cx; ++x)
				{
					line[0] = pix->red;
					line[1] = pix->green;
					line[2] = pix->blue;

					line += 3;
					pix++;
				}
			}

			b.Swap(bmp);

			DestroyImage(sharp);
		}

		DestroyImage(img);
	}

	view.DisplayBitmap(bmp);
	bmp.Save(L"c:\\resized.bmp");
#endif
}
예제 #4
0
void CatalogImages::Impl::ProcessFiles(int img_size, int jpeg_compression_level)
{
    const size_t count= files_.size();

    counter_ = 0;

    for (size_t i= 0; i < count; ++i)
    {
        if (parentWnd_)
            ::PostMessage(parentWnd_, MESSAGE, i, IMG_PROCESSING);

        if (break_)
            return;

        const Path& path= files_[i].first;

        PhotoFactory::CreateFn fn= 0;
        int id= 0;

        if (!GetPhotoFactory().MatchPhotoType(path.GetExtension(), fn, id))
        {
            ASSERT(false);
            continue;
        }

        SmartPhotoPtr photo(fn());

        try
        {
            CatalogImgRecord img;

//			ExifBlock exif;
//			exif.clear();

            bool has_exif= photo->Scan(path.c_str(), img.exif_, false, nullptr);	// scan image to find EXIF data

            if (!has_exif && readOnlyPhotosWithEXIF_)
                continue;

            if (!has_exif || photo->GetDateTime().is_not_a_date_time())
                ReadFileTimeStamp(*photo, path);

            uint64 fileLength= 0;
            // write to db

            img.type_ = id;

            // get file length and last write time
            {
                WIN32_FIND_DATA findFileData;
                HANDLE find= ::FindFirstFile(path.c_str(), &findFileData);
                if (find != INVALID_HANDLE_VALUE)
                {
                    VERIFY(::FindClose(find));
                    fileLength = uint64(findFileData.nFileSizeLow) + (uint64(findFileData.nFileSizeHigh) << 32);

                    img.time_stamp_ = findFileData.ftLastWriteTime;
                    img.access_time_ = findFileData.ftLastAccessTime;
                    img.creation_time_ = findFileData.ftCreationTime;
                    img.file_attribs_ = findFileData.dwFileAttributes;
                }
            }
//			uint64 fileLength= path.GetFileLength();

            //photo->dir_visited_ = static_cast<uint32>(dir_visited);
            photo->SetFileSize(fileLength);
            photo->SetPhotoName(path.GetFileName());
            photo->SetPhysicalPath(path);
            photo->exif_data_present_ = has_exif;

            //			SetAutoRotationFlag(photo.get());

            img.path_ = String2WStr(path);
            img.make_ = String2WStr(photo->GetMake());
            img.model_ = String2WStr(photo->GetModel());
            img.orientation_ = photo->OrientationField();

            img.file_size_ = fileLength;
//			find.GetLastWriteTime(&img.time_stamp_);
            //photo->index_.Serialize(img.buf_index_);

            // verify this: ===========
            //		img.jpeg_offset_ = photo->jpeg_offset_;
            // HACK: this is orientation extracted from CRW file; when reading info from
            // cache CRW is not scanned, so orientation cannot be set
            img.exif_orientation_ = has_exif ? 0u : photo->OrientationField();
            // =========================

            // EXIF block
            img.has_exif_ = has_exif;
//			img.exif_ifd_offset_ = static_cast<int32>(exif.ifd0Start);
//			if (exif.is_raw)
//				img.exif_type_ = exif.bigEndianByteOrder ?
//					CatalogImgRecord::RAW_MM_EXIF_BLOCK : CatalogImgRecord::RAW_II_EXIF_BLOCK;
//			else
//				img.exif_type_ = CatalogImgRecord::JPEG_EXIF_BLOCK;
//			img.exif_.swap(exif.exif_buffer);

            // prepare preview
            Dib bmp;
            CSize thumbnail_size(img_size, img_size);
            CImageDecoderPtr decoder= photo->GetDecoder();
            bool ycbcr_image= true;
            ImageStat stat= decoder->DecodeImgToYCbCr(bmp, thumbnail_size, true);
            if (stat != IS_OK)
            {
                ycbcr_image = false;

                if (stat == IS_OPERATION_NOT_SUPPORTED)
                    stat = decoder->DecodeImg(bmp, thumbnail_size, true);
            }

            if (stat != IS_OK || !bmp.IsValid())
            {
                failed_.push_back(path);
                continue;
            }

            // if EXIF indicates rotation and photo is already physically rotated AND exif reset EXIF orientation
            // flag back to normal to avoid problems later on...
            PhotoInfo::ImgOrientation orient= photo->GetOrientation();
            if ((orient == PhotoInfo::ORIENT_90CCW || orient == PhotoInfo::ORIENT_90CW) &&
                    photo->GetWidth() > photo->GetHeight() && bmp.GetWidth() < bmp.GetHeight())
            {
                //photo->orientation_ = 0;
                std::swap(img.img_width_, img.img_height_);
                uint32 w= photo->GetWidth();
                uint32 h= photo->GetHeight();
                photo->SetSize(h, w);
            }
            else if ((orient == PhotoInfo::ORIENT_NORMAL || orient == PhotoInfo::ORIENT_NO_INFO ||
                      orient == PhotoInfo::ORIENT_UNKNOWN) &&
                     photo->GetWidth() > photo->GetHeight() && bmp.GetWidth() < bmp.GetHeight())
            {
                // orientation is 'normal', but reported size and size of decoded image do not agree
                uint32 w= photo->GetWidth();
                uint32 h= photo->GetHeight();
                photo->SetSize(h, w);
            }

            img.photo_width_ = photo->GetWidth();
            img.photo_height_ = photo->GetHeight();

            //TODO: convert non-ycbcr from rgb if needed

            // calculate 'index' using YCbCr image
            photo->index_.CalcHistogram(bmp);
            photo->index_.Serialize(img.index_);

            // now to RGB
            if (ycbcr_image)
                bmp.ConvertYCbCr2RGB();

            Dib thm;	// little thumbnail
            if (img_size > 160)
                bmp.ResizeToFit(CSize(160, 160), Dib::RESIZE_HALFTONE, thm);

            CSize size= bmp.GetSize();
            int big= img_size;
            if (size.cx > big || size.cy > big)
                bmp.ResizeToFit(CSize(big, big), Dib::RESIZE_HALFTONE);

            img.img_width_ = bmp.GetWidth();
            img.img_height_ = bmp.GetHeight();

            // compress preview into JPEG
            JPEGEncoder enc(jpeg_compression_level, false, false);

            if (thm.IsValid())
            {
                // we have both little thumbnail image and preview image
                {
                    CMemoryDataDestination memdest;
                    enc.Encode(memdest, &thm);
                    memdest.SwapJPEG(img.thumbnail_);
                }
                {
                    CMemoryDataDestination memdest;
                    enc.Encode(memdest, &bmp);
                    memdest.SwapJPEG(img.preview_);
                }
            }
            else
            {
                // only small preview available;
                // store it in the thumbnail leaving preview field empty

                CMemoryDataDestination memdest;
                enc.Encode(memdest, &bmp);
                memdest.SwapJPEG(img.thumbnail_);

                img.preview_.clear();
            }

            // IPTC present?
            //if (photo->IPTC_.get())
            //	img.iptc_.reset(photo->IPTC_.release());
            if (photo->HasMetadata())
            {
                img.iptc_.reset(new IPTCRecord());
                photo->GetIPTCInfo(*img.iptc_);
            }

            img.description_ = photo->GetExifDescription();
            img.marker_index_ = photo->GetFileTypeIndex();

            //TODO: store XMP too!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

//TODO:
//	grab tags;
//	and description;
            //			EliminateNonPrintableChars(photo->photo_desc_);
            //			PostProcessTime(photo.get());

            CatalogHeader::DirPtr dir= files_[i].second;
            img.dir_visited_ = dir->id_;

            // add/modify record
            std::vector<uint8> buf;
            img.Serialize(buf, 1);
            uint64 record_offset= dbImages_.Append(buf);

            // examine tags
            if (!photo->GetTags().empty())	// has tags?
            {
                PhotoTags::const_iterator end= photo->GetTags().end();

                for (PhotoTags::const_iterator it = photo->GetTags().begin(); it != end; ++it)
                    tags_[*it].push_back(record_offset);
            }

            if (dir->records_.empty())
                dir->records_.reserve(dir->reserved_capacity_);

            if (dir->records_.size() < dir->reserved_capacity_)
                dir->records_.push_back(record_offset);
            else
            {
                ASSERT(false);
                continue;
            }

            ++counter_;
        }
        catch (MemPointer::MemPtrException&)
        {
            CString msg= _T("Error parsing file: ");
            msg += path.c_str();
            ::ShowMessageBox(msg);
        }
        catch (CMemoryException*)
        {
            CString msg= _T("Out of memory reading file: ");
            msg += path.c_str();
            ::ShowMessageBox(msg);
        }
        catch (JPEGException& ex)
        {
            CString msg= _T("Error processing file: ");
            msg += path.c_str();
            msg += _T("\n\n");
            msg += ex.GetMessage();
            ::ShowMessageBox(msg);
        }
#ifndef _DEBUG
        catch (...)
        {
//			ASSERT(false);
        }
#endif

    }
}