1/*
2 * Copyright 2005-2006, Axel D��rfler, axeld@pinc-software.de. All rights reserved.
3 * Distributed under the terms of the MIT License.
4 */
5
6
7#include "ICOTranslator.h"
8
9#include <Catalog.h>
10#include <stdlib.h>
11#include <stdio.h>
12#include <string.h>
13
14#include <Catalog.h>
15
16#include "ConfigView.h"
17#include "ICO.h"
18
19
20#undef B_TRANSLATION_CONTEXT
21#define B_TRANSLATION_CONTEXT "ICOTranslator"
22
23
24const char *kDocumentCount = "/documentCount";
25const char *kDocumentIndex = "/documentIndex";
26
27#define kICOMimeType "image/vnd.microsoft.icon"
28#define kICOName "Windows icon"
29	// I'm lazy - structure initializers don't like const variables...
30
31
32// The input formats that this translator supports.
33static const translation_format sInputFormats[] = {
34	{
35		ICO_IMAGE_FORMAT,
36		B_TRANSLATOR_BITMAP,
37		ICO_IN_QUALITY,
38		ICO_IN_CAPABILITY,
39		kICOMimeType,
40		kICOName
41	},
42	{
43		B_TRANSLATOR_BITMAP,
44		B_TRANSLATOR_BITMAP,
45		BITS_IN_QUALITY,
46		BITS_IN_CAPABILITY,
47		"image/x-be-bitmap",
48		"Be Bitmap Format (ICOTranslator)"
49	},
50};
51
52// The output formats that this translator supports.
53static const translation_format sOutputFormats[] = {
54	{
55		ICO_IMAGE_FORMAT,
56		B_TRANSLATOR_BITMAP,
57		ICO_OUT_QUALITY,
58		ICO_OUT_CAPABILITY,
59		kICOMimeType,
60		kICOName
61	},
62	{
63		B_TRANSLATOR_BITMAP,
64		B_TRANSLATOR_BITMAP,
65		BITS_OUT_QUALITY,
66		BITS_OUT_CAPABILITY,
67		"image/x-be-bitmap",
68		"Be Bitmap Format (ICOTranslator)"
69	},
70};
71
72// Default settings for the Translator
73static const TranSetting sDefaultSettings[] = {
74	{B_TRANSLATOR_EXT_HEADER_ONLY, TRAN_SETTING_BOOL, false},
75	{B_TRANSLATOR_EXT_DATA_ONLY, TRAN_SETTING_BOOL, false}
76};
77
78const uint32 kNumInputFormats = sizeof(sInputFormats) / sizeof(translation_format);
79const uint32 kNumOutputFormats = sizeof(sOutputFormats) / sizeof(translation_format);
80const uint32 kNumDefaultSettings = sizeof(sDefaultSettings) / sizeof(TranSetting);
81
82
83ICOTranslator::ICOTranslator()
84	: BaseTranslator(B_TRANSLATE("Windows icons"),
85		B_TRANSLATE("Windows icon translator"),
86		ICO_TRANSLATOR_VERSION,
87		sInputFormats, kNumInputFormats,
88		sOutputFormats, kNumOutputFormats,
89		"ICOTranslator_Settings",
90		sDefaultSettings, kNumDefaultSettings,
91		B_TRANSLATOR_BITMAP, ICO_IMAGE_FORMAT)
92{
93}
94
95
96ICOTranslator::~ICOTranslator()
97{
98}
99
100
101status_t
102ICOTranslator::DerivedIdentify(BPositionIO *stream,
103	const translation_format *format, BMessage *ioExtension,
104	translator_info *info, uint32 outType)
105{
106	if (!outType)
107		outType = B_TRANSLATOR_BITMAP;
108	if (outType != B_TRANSLATOR_BITMAP && outType != ICO_IMAGE_FORMAT)
109		return B_NO_TRANSLATOR;
110
111	int32 bitsPerPixel;
112	uint8 type;
113	if (ICO::identify(ioExtension, *stream, type, bitsPerPixel) != B_OK)
114		return B_NO_TRANSLATOR;
115
116	info->type = ICO_IMAGE_FORMAT;
117	info->group = B_TRANSLATOR_BITMAP;
118	info->quality = ICO_IN_QUALITY;
119	info->capability = ICO_IN_CAPABILITY;
120	snprintf(info->name, sizeof(info->name),
121		B_TRANSLATE("Windows %s %ld bit image"),
122		type == ICO::kTypeIcon ? B_TRANSLATE("Icon") : B_TRANSLATE("Cursor"),
123		bitsPerPixel);
124	strcpy(info->MIME, kICOMimeType);
125
126	return B_OK;
127}
128
129
130status_t
131ICOTranslator::DerivedTranslate(BPositionIO *source,
132	const translator_info *info, BMessage *ioExtension,
133	uint32 outType, BPositionIO *target, int32 baseType)
134{
135	if (!outType)
136		outType = B_TRANSLATOR_BITMAP;
137	if (outType != B_TRANSLATOR_BITMAP && outType != ICO_IMAGE_FORMAT)
138		return B_NO_TRANSLATOR;
139
140	switch (baseType) {
141		case 1:
142		{
143			if (outType != ICO_IMAGE_FORMAT)
144				return B_NO_TRANSLATOR;
145
146			// Source is in bits format - this has to be done here, because
147			// identify_bits_header() is a member of the BaseTranslator class...
148			TranslatorBitmap bitsHeader;
149			status_t status = identify_bits_header(source, NULL, &bitsHeader);
150			if (status != B_OK)
151				return status;
152
153			return ICO::convert_bits_to_ico(ioExtension, *source, bitsHeader, *target);
154		}
155
156		case 0:
157		{
158			// source is NOT in bits format
159			if (outType != B_TRANSLATOR_BITMAP)
160				return B_NO_TRANSLATOR;
161
162			return ICO::convert_ico_to_bits(ioExtension, *source, *target);
163		}
164
165		default:
166			return B_NO_TRANSLATOR;
167	}
168}
169
170
171status_t
172ICOTranslator::DerivedCanHandleImageSize(float width, float height) const
173{
174	if (!ICO::is_valid_size((int)width) || !ICO::is_valid_size((int)height))
175		return B_NO_TRANSLATOR;
176	return B_OK;
177}
178
179
180BView *
181ICOTranslator::NewConfigView(TranslatorSettings *settings)
182{
183	return new ConfigView();
184}
185
186
187//	#pragma mark -
188
189
190BTranslator *
191make_nth_translator(int32 n, image_id you, uint32 flags, ...)
192{
193	if (n != 0)
194		return NULL;
195
196	return new ICOTranslator();
197}
198
199