apply wayland coding style
[platform/core/uifw/libtdm.git] / src / tdm_helper.c
1 #ifdef HAVE_CONFIG_H
2 #include "config.h"
3 #endif
4
5 #include <png.h>
6 #include <string.h>
7 #include <tbm_surface.h>
8 #include <tbm_surface_internal.h>
9 #include <string.h>
10
11 #include "tdm.h"
12 #include "tdm_private.h"
13
14 #define PNG_DEPTH 8
15
16 static const char *dump_prefix[2] = {"png", "yuv"};
17
18 static void
19 _tdm_helper_dump_raw(const char *file, void *data1, int size1, void *data2,
20                      int size2, void *data3, int size3)
21 {
22         unsigned int *blocks;
23         FILE *fp = fopen(file, "w+");
24         TDM_RETURN_IF_FAIL(fp != NULL);
25
26         blocks = (unsigned int *)data1;
27         fwrite(blocks, 1, size1, fp);
28
29         if (size2 > 0) {
30                 blocks = (unsigned int *)data2;
31                 fwrite(blocks, 1, size2, fp);
32         }
33
34         if (size3 > 0) {
35                 blocks = (unsigned int *)data3;
36                 fwrite(blocks, 1, size3, fp);
37         }
38
39         fclose(fp);
40 }
41
42 static void
43 _tdm_helper_dump_png(const char *file, const void *data, int width,
44                      int height)
45 {
46         FILE *fp = fopen(file, "wb");
47         TDM_RETURN_IF_FAIL(fp != NULL);
48
49         png_structp pPngStruct =
50                 png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
51         if (!pPngStruct) {
52                 fclose(fp);
53                 return;
54         }
55
56         png_infop pPngInfo = png_create_info_struct(pPngStruct);
57         if (!pPngInfo) {
58                 png_destroy_write_struct(&pPngStruct, NULL);
59                 fclose(fp);
60                 return;
61         }
62
63         png_init_io(pPngStruct, fp);
64         png_set_IHDR(pPngStruct,
65                      pPngInfo,
66                      width,
67                      height,
68                      PNG_DEPTH,
69                      PNG_COLOR_TYPE_RGBA,
70                      PNG_INTERLACE_NONE,
71                      PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
72
73         png_set_bgr(pPngStruct);
74         png_write_info(pPngStruct, pPngInfo);
75
76         const int pixel_size = 4;       // RGBA
77         png_bytep *row_pointers =
78                 png_malloc(pPngStruct, height * sizeof(png_byte *));
79
80         unsigned int *blocks = (unsigned int *)data;
81         int y = 0;
82         int x = 0;
83
84         for (; y < height; ++y) {
85                 png_bytep row =
86                         png_malloc(pPngStruct, sizeof(png_byte) * width * pixel_size);
87                 row_pointers[y] = (png_bytep)row;
88                 for (x = 0; x < width; ++x) {
89                         unsigned int curBlock = blocks[y * width + x];
90                         row[x * pixel_size] = (curBlock & 0xFF);
91                         row[1 + x * pixel_size] = (curBlock >> 8) & 0xFF;
92                         row[2 + x * pixel_size] = (curBlock >> 16) & 0xFF;
93                         row[3 + x * pixel_size] = (curBlock >> 24) & 0xFF;
94                 }
95         }
96
97         png_write_image(pPngStruct, row_pointers);
98         png_write_end(pPngStruct, pPngInfo);
99
100         for (y = 0; y < height; y++)
101                 png_free(pPngStruct, row_pointers[y]);
102         png_free(pPngStruct, row_pointers);
103
104         png_destroy_write_struct(&pPngStruct, &pPngInfo);
105
106         fclose(fp);
107 }
108
109 EXTERN void
110 tdm_helper_dump_buffer(tbm_surface_h buffer, const char *file)
111 {
112         tbm_surface_info_s info;
113         int len;
114         const char *prefix;
115
116         TDM_RETURN_IF_FAIL(buffer != NULL);
117         TDM_RETURN_IF_FAIL(file != NULL);
118
119         tbm_surface_get_info(buffer, &info);
120
121         len = strnlen(file, 1024);
122         if (info.format == TBM_FORMAT_ARGB8888 || info.format == TBM_FORMAT_XRGB8888)
123                 prefix = dump_prefix[0];
124         else
125                 prefix = dump_prefix[1];
126
127         if (strncmp(file + (len - 3), prefix, 3)) {
128                 TDM_ERR("can't dump to '%s' file", file + (len - 3));
129                 return;
130         }
131
132         switch (info.format) {
133         case TBM_FORMAT_ARGB8888:
134         case TBM_FORMAT_XRGB8888:
135                 _tdm_helper_dump_png(file, info.planes[0].ptr,
136                                      info.planes[0].stride >> 2, info.height);
137                 break;
138         case TBM_FORMAT_YVU420:
139         case TBM_FORMAT_YUV420:
140                 _tdm_helper_dump_raw(file,
141                                      info.planes[0].ptr + info.planes[0].offset,
142                                      info.planes[0].stride * info.height,
143                                      info.planes[1].ptr + info.planes[1].offset,
144                                      info.planes[1].stride * (info.height >> 1),
145                                      info.planes[2].ptr + info.planes[2].offset,
146                                      info.planes[2].stride * (info.height >> 1));
147                 break;
148         case TBM_FORMAT_NV12:
149         case TBM_FORMAT_NV21:
150                 _tdm_helper_dump_raw(file,
151                                      info.planes[0].ptr + info.planes[0].offset,
152                                      info.planes[0].stride * info.height,
153                                      info.planes[1].ptr + info.planes[1].offset,
154                                      info.planes[1].stride * (info.height >> 1), NULL,
155                                      0);
156                 break;
157         case TBM_FORMAT_YUYV:
158         case TBM_FORMAT_UYVY:
159                 _tdm_helper_dump_raw(file,
160                                      info.planes[0].ptr + info.planes[0].offset,
161                                      info.planes[0].stride * info.height, NULL, 0,
162                                      NULL, 0);
163                 break;
164         default:
165                 TDM_ERR("can't dump %c%c%c%c buffer", FOURCC_STR (info.format));
166                 return;
167         }
168
169         TDM_INFO("dump %s", file);
170 }