6 #include "icns_class.h"
9 uint32
ClassDispatch (Class
*cl
, Object
*o
, Msg msg
);
11 Class
*initDTClass (struct ClassBase
*libBase
) {
13 SuperClassBase
= IExec
->OpenLibrary("datatypes/picture.datatype", 52);
15 cl
= IIntuition
->MakeClass(libBase
->libNode
.lib_Node
.ln_Name
, PICTUREDTCLASS
, NULL
, 0, 0);
17 cl
->cl_Dispatcher
.h_Entry
= (HOOKFUNC
)ClassDispatch
;
18 cl
->cl_UserData
= (uint32
)libBase
;
19 IIntuition
->AddClass(cl
);
21 IExec
->CloseLibrary(SuperClassBase
);
27 BOOL
freeDTClass (struct ClassBase
*libBase
, Class
*cl
) {
30 res
= IIntuition
->FreeClass(cl
);
32 IExec
->CloseLibrary(SuperClassBase
);
38 static int32
ConvertICNS (Class
*cl
, Object
*o
, BPTR file
, struct BitMapHeader
*bmh
,
39 uint32 index
, uint32
*total
);
40 static int32
GetICNS (Class
*cl
, Object
*o
, struct TagItem
*tags
);
42 uint32
ClassDispatch (Class
*cl
, Object
*o
, Msg msg
) {
43 struct ClassBase
*libBase
= (struct ClassBase
*)cl
->cl_UserData
;
46 switch (msg
->MethodID
) {
49 ret
= IIntuition
->IDoSuperMethodA(cl
, o
, msg
);
52 error
= GetICNS(cl
, (Object
*)ret
, ((struct opSet
*)msg
)->ops_AttrList
);
54 IIntuition
->ICoerceMethod(cl
, (Object
*)ret
, OM_DISPOSE
);
56 IDOS
->SetIoErr(error
);
62 ret
= IIntuition
->IDoSuperMethodA(cl
, o
, msg
);
70 static int32
ReadC1A1 (Class
*cl
, Object
*o
, BPTR file
, struct BitMapHeader
*bmh
,
71 struct IconInfo
*info
);
72 static int32
ReadCLUT4_8 (Class
*cl
, Object
*o
, BPTR file
, struct BitMapHeader
*bmh
,
73 struct IconInfo
*info
);
74 static int32
ReadARGB32 (Class
*cl
, Object
*o
, BPTR file
, struct BitMapHeader
*bmh
,
75 struct IconInfo
*info
);
77 static int32
ConvertICNS (Class
*cl
, Object
*o
, BPTR file
, struct BitMapHeader
*bmh
,
78 uint32 index
, uint32
*total
)
80 struct ClassBase
*libBase
= (struct ClassBase
*)cl
->cl_UserData
;
81 int32 status
, error
= OK
;
82 struct ResourceHeader rsh
;
83 struct ElementHeader elem
;
85 int32 (*ReadFunc
) (Class
*cl
, Object
*o
, BPTR file
, struct BitMapHeader
*bmh
,
86 struct IconInfo
*info
);
88 status
= IDOS
->Read(file
, &rsh
, sizeof(struct ResourceHeader
));
89 if (status
!= sizeof(struct ResourceHeader
)) {
90 return ReadError(status
);
93 if (rsh
.ResourceType
!= RST_ICNS
) {
94 return ERROR_OBJECT_WRONG_TYPE
;
98 if (error
= ParseElements(cl
, file
, &elem
, &info
, 0, 0, total
)) return error
;
99 if (index
>= *total
) return DTERROR_NOT_AVAILABLE
;
102 if (error
= ParseElements(cl
, file
, &elem
, &info
, 0, index
, NULL
)) return error
;
104 bmh
->bmh_Width
= info
.Width
;
105 bmh
->bmh_Height
= info
.Height
;
106 bmh
->bmh_Depth
= info
.BitDepth
;
108 info
.DataSize
= elem
.ElementSize
- sizeof(elem
);
109 info
.Data
= IExec
->AllocVec(info
.DataSize
, MEMF_SHARED
);
111 error
= ERROR_NO_FREE_STORE
;
115 status
= IDOS
->Read(file
, info
.Data
, info
.DataSize
);
116 if (status
!= info
.DataSize
) {
117 error
= ReadError(status
);
122 switch (bmh
->bmh_Depth
) {
129 ReadFunc
= ReadCLUT4_8
;
132 bmh
->bmh_Masking
= mskHasAlpha
;
133 ReadFunc
= ReadARGB32
;
137 error
= DTERROR_UNKNOWN_COMPRESSION
;
141 error
= ReadFunc(cl
, o
, file
, bmh
, &info
);
144 IExec
->FreeVec(info
.Data
);
149 static int32
ReadC1A1 (Class
*cl
, Object
*o
, BPTR file
, struct BitMapHeader
*bmh
,
150 struct IconInfo
*info
)
152 struct ClassBase
*libBase
= (struct ClassBase
*)cl
->cl_UserData
;
154 uint8
*mask
, *src
, *dst
;
158 struct ColorRegister
*cmap
= NULL
;
159 uint32
*cregs
= NULL
;
161 bpr
= (bmh
->bmh_Width
+ 7) >> 3;
162 if (info
->DataSize
!= ((bpr
*bmh
->bmh_Height
) << 1)) {
163 return DTERROR_INVALID_DATA
;
166 bm
= IGraphics
->AllocBitMap(bmh
->bmh_Width
, bmh
->bmh_Height
, 1, 0, NULL
);
167 mask
= IGraphics
->AllocRaster(bmh
->bmh_Width
, bmh
->bmh_Height
);
169 IGraphics
->FreeBitMap(bm
);
170 if (mask
) IGraphics
->FreeRaster(mask
, bmh
->bmh_Width
, bmh
->bmh_Height
);
171 return ERROR_NO_FREE_STORE
;
175 dst
= (uint8
*)bm
->Planes
[0];
176 mod
= bm
->BytesPerRow
;
177 for (y
= 0; y
< bmh
->bmh_Width
; y
++) {
178 IExec
->CopyMem(src
, dst
, bpr
);
183 for (y
= 0; y
< bmh
->bmh_Width
; y
++) {
184 IExec
->CopyMem(src
, dst
, bpr
);
189 IDataTypes
->SetDTAttrs(o
, NULL
, NULL
,
190 DTA_NominalHoriz
, bmh
->bmh_Width
,
191 DTA_NominalVert
, bmh
->bmh_Height
,
193 PDTA_MaskPlane
, mask
,
195 bmh
->bmh_Masking
= mskHasMask
;
202 static int32
ReadCLUT4_8 (Class
*cl
, Object
*o
, BPTR file
, struct BitMapHeader
*bmh
,
203 struct IconInfo
*info
)
205 struct ClassBase
*libBase
= (struct ClassBase
*)cl
->cl_UserData
;
208 int32 level
= 0, error
= OK
;
210 struct ElementHeader elem
;
212 pixel_count
= bmh
->bmh_Width
* bmh
->bmh_Height
;
213 if (info
->DataSize
!= ((pixel_count
* info
->BitDepth
) >> 3)) {
214 return DTERROR_INVALID_DATA
;
217 IDataTypes
->SetDTAttrs(o
, NULL
, NULL
,
218 DTA_NominalHoriz
, bmh
->bmh_Width
,
219 DTA_NominalVert
, bmh
->bmh_Height
,
220 PDTA_SourceMode
, PMODE_V43
,
221 DTA_ErrorLevel
, &level
,
222 DTA_ErrorNumber
, &error
,
224 if (level
) return error
;
226 if (info
->BitDepth
== 4) {
229 data
= IExec
->AllocVec(pixel_count
, 0);
230 if (!data
) return ERROR_NO_FREE_STORE
;
233 for (y
= 0; y
< bmh
->bmh_Height
; y
++) {
234 for (x
= 0; x
< bmh
->bmh_Width
; x
+= 2) {
244 IIntuition
->IDoSuperMethod(cl
, o
,
245 PDTM_WRITEPIXELARRAY
, data
, PBPAFMT_LUT8
,
246 bmh
->bmh_Width
, 0, 0, bmh
->bmh_Width
, bmh
->bmh_Height
);
248 if (info
->BitDepth
== 4) {
249 IExec
->FreeVec(data
);
252 SetCMAP(cl
, o
, 1 << info
->BitDepth
);
254 IExec
->FreeVec(info
->Data
);
256 mask_type
= GetMaskType(info
->Type
);
257 error
= mask_type
? ParseElements(cl
, file
, &elem
, info
, mask_type
, 0, NULL
) :
258 DTERROR_NOT_AVAILABLE
;
264 plane_size
= (bmh
->bmh_Width
* bmh
->bmh_Height
) >> 3;
265 if (!IDOS
->ChangeFilePosition(file
, plane_size
, OFFSET_CURRENT
)) {
266 return IDOS
->IoErr();
269 mask
= IGraphics
->AllocRaster(bmh
->bmh_Width
, bmh
->bmh_Height
);
270 if (!mask
) return ERROR_NO_FREE_STORE
;
272 status
= IDOS
->Read(file
, mask
, plane_size
);
273 if (status
!= plane_size
) {
274 IGraphics
->FreeRaster(mask
, bmh
->bmh_Width
, bmh
->bmh_Height
);
275 return ReadError(status
);
278 IDataTypes
->SetDTAttrs(o
, NULL
, NULL
,
279 PDTA_MaskPlane
, mask
,
281 bmh
->bmh_Masking
= mskHasMask
;
283 if (error
== DTERROR_NOT_AVAILABLE
) error
= OK
;
288 static int32
ReadARGB32 (Class
*cl
, Object
*o
, BPTR file
, struct BitMapHeader
*bmh
,
289 struct IconInfo
*info
)
291 struct ClassBase
*libBase
= (struct ClassBase
*)cl
->cl_UserData
;
294 int32 status
, level
= 0, error
= OK
;
299 bpr
= bmh
->bmh_Width
<< 2;
300 pixel_count
= bmh
->bmh_Width
* bmh
->bmh_Height
;
301 decoded_size
= pixel_count
<< 2;
302 buf
= IExec
->AllocVec(decoded_size
, MEMF_SHARED
);
304 return ERROR_NO_FREE_STORE
;
307 IDataTypes
->SetDTAttrs(o
, NULL
, NULL
,
308 DTA_NominalHoriz
, bmh
->bmh_Width
,
309 DTA_NominalVert
, bmh
->bmh_Height
,
310 PDTA_SourceMode
, PMODE_V43
,
311 DTA_ErrorLevel
, &level
,
312 DTA_ErrorNumber
, &error
,
319 if (bmh
->bmh_Width
>= 256 && bmh
->bmh_Height
>= 256) {
320 error
= icns_jp2_decode(info
, buf
);
322 struct ElementHeader elem
;
324 error
= rle24_decode(info
->Data
, info
->DataSize
, buf
, decoded_size
, pixel_count
);
327 IExec
->FreeVec(info
->Data
);
329 mask
= IExec
->AllocVec(pixel_count
, MEMF_SHARED
);
331 error
= ERROR_NO_FREE_STORE
;
335 mask_type
= GetMaskType(info
->Type
);
336 error
= mask_type
? ParseElements(cl
, file
, &elem
, info
, mask_type
, 0, NULL
) :
337 DTERROR_NOT_AVAILABLE
;
341 status
= IDOS
->Read(file
, mask
, pixel_count
);
342 if (status
!= pixel_count
) {
343 error
= ReadError(status
);
348 pixels_left
= pixel_count
;
349 while (pixels_left
--) {
354 if (error
== DTERROR_NOT_AVAILABLE
) error
= OK
;
358 IIntuition
->IDoSuperMethod(cl
, o
,
359 PDTM_WRITEPIXELARRAY
, buf
, PBPAFMT_ARGB
,
360 bpr
, 0, 0, bmh
->bmh_Width
, bmh
->bmh_Height
);
363 IExec
->FreeVec(mask
);
368 static int32
GetICNS (Class
*cl
, Object
*o
, struct TagItem
*tags
) {
369 struct ClassBase
*libBase
= (struct ClassBase
*)cl
->cl_UserData
;
370 struct BitMapHeader
*bmh
= NULL
;
373 int32 error
= ERROR_REQUIRED_ARG_MISSING
;
374 BPTR file
= (BPTR
)NULL
;
375 uint32 whichpic
, *numpics
;
377 filename
= (char *)IUtility
->GetTagData(DTA_Name
, (uint32
)"Untitled", tags
);
378 whichpic
= IUtility
->GetTagData(PDTA_WhichPicture
, 0, tags
);
379 numpics
= (uint32
*)IUtility
->GetTagData(PDTA_GetNumPictures
, (uint32
)NULL
, tags
);
381 IDataTypes
->GetDTAttrs(o
,
382 PDTA_BitMapHeader
, &bmh
,
384 DTA_SourceType
, &srctype
,
387 /* Do we have everything we need? */
388 if (bmh
&& file
&& srctype
== DTST_FILE
) {
389 error
= ConvertICNS(cl
, o
, file
, bmh
, whichpic
, numpics
);
391 IDataTypes
->SetDTAttrs(o
, NULL
, NULL
,
392 DTA_ObjName
, IDOS
->FilePart(filename
),
396 if (srctype
!= DTST_FILE
) error
= ERROR_NOT_IMPLEMENTED
;