Simple use of picture datatype to show JPG file

4 posts / 0 new
Last post
tbreeden
tbreeden's picture
Offline
Last seen: 6 years 1 week ago
Joined: 2010-12-09 03:10
Simple use of picture datatype to show JPG file

I'm struggling with an attempt to simply open a picture file via DataTypes, add the object to a window, and get a reasonably good image. This is AOS4.1 Upd 4, Picture Datatype 53.6, JPG Datatype 53.5

I'm calling NewDTObjectA() on the file name successfully.
I GetDTAttrsA() successfully for DTANominalVert and DTANominalHoriz.
Open a WB window plenty big enough.
SetDTAttrsA() for GA_Left, GA_Top, GA_Width, and GA_Height to avoid the window borders.
AddDTObject() to the window.
Delay a bit and then RefreshDTObjectA().

I'm expecting to see something like Multiview shows, and it does for IFF and GIF files, but JPG files show the image, but in a poor quality. It looks like the picture has attempted to use too few colors and dithered into graininess.

GetDTAttrsA() for PDTANumColors always returns 16.
I've tried SetDTAttrsA() to increase that value, and to set PDTA_NumAlloc to a high value. But no change.

Can anyone point me to the type of things Multiview must be doing with this?

Thanks,

Tom

OldFart
OldFart's picture
Offline
Last seen: 1 day 5 hours ago
Joined: 2010-11-30 14:09
Hi Tom, Here's an example

Hi Tom,

Here's an example that does woerk. It is a rewrite (= turned to OS4) of one of corto's sources.

  1. /*
  2. ** Example number 1
  3. **
  4. ** Original author: 'Corto'
  5. **
  6. ** Converted to OS4-style by Tjitte 'OldFart' de Wolff
  7. **
  8. ** June 2011
  9. **
  10. */
  11.  
  12. /*
  13.  * Exemple d'utilisation des datatypes avec l'affichage d'une image dans
  14.  * une fenêtre du Workbench. On ne traite pas le cas où l'on souhaite
  15.  * afficher l'image dans un écran privé.
  16.  * Une fonction a été créée uniquement dans le but d'afficher un fichier
  17.  * image dans une fenêtre correctement ouverte. Ainsi, cette fonction
  18.  * devrait être réutilisable dans d'autres programmes.
  19.  *
  20.  * L'appel à la méthode FRAMEBOX ... je ne sais toujours pas à quoi ça sert !
  21.  *
  22.  * Un autre programme d'exemple sera nécessaire (si demandé) pour montrer
  23.  * comment afficher un image sur un écran privé, en affectant la palette
  24.  * de l'image à l'écran.
  25.  */
  26.  
  27. #include <exec/exec.h>
  28. #include <dos/dos.h>
  29. #include <graphics/gfx.h>
  30. #include <intuition/intuition.h>
  31. #include <graphics/display.h>
  32.  
  33. #include <datatypes/datatypesclass.h>
  34. #include <datatypes/pictureclass.h>
  35.  
  36. #include <proto/exec.h>
  37. #include <proto/intuition.h>
  38. #include <proto/dos.h>
  39. #include <proto/graphics.h>
  40. #include <proto/datatypes.h>
  41.  
  42. // Prototypes des fonctions
  43.  
  44. static int loadPictureIntoWindow(char *pictureName, struct Window *pictureWindow);
  45. static void waitInput(struct Window *);
  46.  
  47. /*
  48.  * loadPictureIntoWindow()
  49.  *
  50.  * Charge une image grâce aux datatypes et l'affiche dans une fenêtre
  51.  * préalablement ouverte.
  52.  * Codes d'erreur possibles :
  53.  * 0 : pas d'erreur
  54.  * 2 : échec sur la création de l'objet Datatype
  55.  * 3 : impossible d'accéder aux infos de l'objet
  56.  * 4 : bitmap inaccessible
  57.  * 5 : échec de l'appel à la méthode interne PROC_LAYOUT
  58.  */
  59. static int loadPictureIntoWindow(char *pictureName, struct Window *pictureWindow)
  60. {
  61. int err = 0;
  62.  
  63. /* 1. Création du datatype */
  64. Object *dtype = IDataTypes->NewDTObject(pictureName, PDTA_DestMode, PMODE_V43,
  65. PDTA_Screen, pictureWindow->WScreen,
  66. PDTA_Remap, TRUE,
  67. PDTA_DitherQuality, 1,
  68. TAG_END);
  69. if (dtype)
  70. {
  71. /* 2. Récupération des infos */
  72. struct BitMapHeader *bmh;
  73.  
  74. if (IDataTypes->GetDTAttrs(dtype, PDTA_BitMapHeader, (ULONG)&bmh, TAG_DONE) == 1)
  75. {
  76. struct FrameInfo fri;
  77. /* 3. Adaptation des dimensions de la fenêtre */
  78. int windowWidth = bmh->bmh_Width + pictureWindow->BorderLeft + pictureWindow->BorderRight;
  79. int windowHeight = bmh->bmh_Height + pictureWindow->BorderTop + pictureWindow->BorderBottom;
  80.  
  81. IIntuition->ChangeWindowBox(pictureWindow, 20, 20, windowWidth, windowHeight);
  82.  
  83. /* 4. Copie du contexte graphique dans le BitMap de la fenêtre */
  84. IIntuition->IDoMethod(dtype, DTM_FRAMEBOX, NULL, &fri, &fri, sizeof(struct FrameInfo), 0);
  85.  
  86. if (fri.fri_Dimensions.Depth > 0)
  87. {
  88. if (IIntuition->IDoMethod(dtype, DTM_PROCLAYOUT, NULL, 1))
  89. {
  90. struct BitMap *bitmap;
  91. struct BitMapHeader *bmhd;
  92.  
  93. if (IDataTypes->GetDTAttrs(dtype, PDTA_DestBitMap, &bitmap,
  94. PDTA_BitMapHeader, (ULONG)&bmhd,
  95. TAG_DONE) == 2)
  96. {
  97. if (bitmap)
  98. {
  99. IGraphics->BltBitMapRastPort(bitmap, 0, 0, pictureWindow->RPort,
  100. pictureWindow->BorderLeft,
  101. pictureWindow->BorderTop,
  102. bmhd->bmh_Width,
  103. bmhd->bmh_Height,
  104. 0xc0);
  105. }
  106. else
  107. {
  108. err = 4;
  109. }
  110. }
  111. else
  112. {
  113. err = 5;
  114. }
  115. }
  116. }
  117. }
  118. else
  119. {
  120. err = 3;
  121. }
  122.  
  123. IDataTypes->DisposeDTObject(dtype);
  124. }
  125. else
  126. {
  127. err = 2;
  128. }
  129.  
  130. return err;
  131. }
  132.  
  133.  
  134. /*
  135.  * Code du programme principal
  136.  *
  137.  * Il doit :
  138.  * - initialiser un écran (ouverture ou récupération du Workbench)
  139.  * - ouvrir une fenêtre capable de recevoir un bitmap
  140.  * - charger l'image dans la fenêtre
  141.  *
  142.  * Si l'écran support est le Workbench alors il faut adapter les couleurs
  143.  * de l'image à charger à la palette de l'écran Workbench.
  144.  * Si un écran propriétaire est ouvert, on peut récupérer la palette
  145.  * de l'image.
  146.  */
  147. int main(int argc, char *argv[])
  148. {
  149. int RC = RETURN_FAIL;
  150.  
  151. // Traitement des arguments
  152. if (argc == 2)
  153. {
  154. char *filename = argv[1];
  155.  
  156. // Lock de l'écran Workbench pour que la fenêtre s'ouvre sur lui
  157. struct Screen *screen = IIntuition->LockPubScreen("Workbench");
  158.  
  159. if (screen)
  160. {
  161. // Ouverture d'une fenêtre avec une taille arbitraire
  162. struct Window *window = IIntuition->OpenWindowTags(NULL, WA_Left, 20,
  163. WA_Top, 20,
  164. WA_Width, 200,
  165. WA_Height, 200,
  166.  
  167. WA_IDCMP, 0
  168. | IDCMP_RAWKEY
  169. | IDCMP_MOUSEBUTTONS
  170. | IDCMP_ACTIVEWINDOW
  171. ,
  172. WA_Title, (ULONG)"Utilisation des datatypes",
  173. WA_CustomScreen, (ULONG)screen,
  174. WA_SizeGadget, FALSE,
  175. WA_DragBar, TRUE,
  176. WA_DepthGadget, TRUE,
  177. WA_CloseGadget, FALSE,
  178. WA_Backdrop, FALSE,
  179. WA_ReportMouse, FALSE,
  180. WA_Borderless, FALSE,
  181. WA_Activate, TRUE,
  182. WA_RMBTrap, TRUE,
  183. WA_SimpleRefresh, FALSE,
  184. TAG_DONE);
  185.  
  186. if (window)
  187. {
  188. IIntuition->SetWindowTitles(window, (APTR) -1, "guru-meditation.net aime les datatypes");
  189.  
  190. // On peut afficher une image dans la fenêtre
  191. if (loadPictureIntoWindow(filename, window) == 0)
  192. {
  193. // Attente d'une touche d'échappement ou d'un clic souris
  194. waitInput(window);
  195.  
  196. RC = RETURN_OK;
  197. }
  198. else
  199. {
  200. IDOS->Printf("Erreur dans le chargement de l'image\n");
  201. }
  202.  
  203. IIntuition->CloseWindow(window);
  204. }
  205. else
  206. {
  207. IDOS->Printf("Impossible d'ouvrir la fenêtre\n");
  208. }
  209.  
  210. IIntuition->UnlockPubScreen(NULL, screen);
  211. }
  212. else
  213. {
  214. IDOS->Printf("Impossible d'accéder à l'écran Workbench\n");
  215. }
  216. }
  217. else
  218. {
  219. IDOS->Printf("Usage : dtype nom_image\n");
  220. }
  221.  
  222. return RC;
  223. }
  224.  
  225.  
  226. /*
  227.  * waitInput
  228.  * Gère les évènements de la fenêtre.
  229.  */
  230. static void waitInput(struct Window *win)
  231. {
  232. BOOL Done = FALSE;
  233. uint32 waitsigs,
  234. portsig = 1L << win->UserPort->mp_SigBit;
  235.  
  236. struct IntuiMessage *imsg = NULL;
  237.  
  238. while (!Done)
  239. {
  240. waitsigs = IExec->Wait(portsig); // Wait ne retourne jamais 0
  241.  
  242. while (imsg = (struct IntuiMessage *)IExec->GetMsg(win->UserPort))
  243. {
  244. // switch puis reply au message
  245. switch(imsg->Class)
  246. {
  247. case IDCMP_RAWKEY:
  248. {
  249. switch(imsg->Code)
  250. {
  251. case 0x45: /* = ESC */
  252. case 0x40: /* = Space */
  253. {
  254. Done = TRUE;
  255. }
  256.  
  257. default:
  258. {
  259. break;
  260. }
  261. }
  262. }
  263.  
  264. case IDCMP_MOUSEBUTTONS:
  265. {
  266. switch(imsg->Code)
  267. {
  268. case IECODE_LBUTTON:
  269. {
  270. Done = TRUE;
  271. }
  272.  
  273. default:
  274. {
  275. break;
  276. }
  277. }
  278. }
  279. }
  280.  
  281. IExec->ReplyMsg((struct Message *)imsg);
  282. }
  283. }
  284. }
  285.  
  286. /*
  287. ** ================================================================================================
  288. ** === End of File ================================================================================
  289. ** ================================================================================================
  290. */

Have fun with it.

OldFart

thomas
thomas's picture
Offline
Last seen: 6 hours 39 min ago
Joined: 2011-05-16 14:23
I'm expecting to see

I'm expecting to see something like Multiview shows, and it does for IFF and GIF files, but JPG files show the image, but in a poor quality. It looks like the picture has attempted to use too few colors and dithered into graininess.

Set PDTA_DestMode,PMODE_V43 in NewDTObject.

tbreeden
tbreeden's picture
Offline
Last seen: 6 years 1 week ago
Joined: 2010-12-09 03:10
@OldFart @thomas Thanks for

@OldFart
@thomas

Thanks for the replies. I had tried PMODE_V43, but set it to the wrong tag, PDTA_SourceMode instead of PDTA_DestMode.

Once I changed to PDTA_DestMode, the picture looks very good, and it is very simple to use DataTypes for the display of JPG as well as GIF and IFF.

Probably accessing the BitMap and other details would be useful for doing something else with the image, but for display it seems to be just

NewDTObject()
AddDTObject()
RefreshDTObject()

nice.

Tom

Log in or register to post comments