@@ -4095,6 +4095,63 @@ void pixmap_copy( fz_pixmap* pm, const fz_pixmap* src, int n)
40954095}
40964096
40974097
4098+ PyObject* ll_JM_color_count (fz_pixmap *pm, PyObject *clip)
4099+ {
4100+ fz_context* ctx = mupdf::internal_context_get ();
4101+ PyObject* rc = PyDict_New ();
4102+ fz_irect irect = fz_pixmap_bbox (ctx, pm);
4103+ irect = fz_intersect_irect (irect, fz_round_rect (JM_rect_from_py (clip)));
4104+ if (fz_is_empty_irect (irect))
4105+ {
4106+ return rc;
4107+ }
4108+ size_t stride = pm->stride ;
4109+ size_t width = irect.x1 - irect.x0 ;
4110+ size_t height = irect.y1 - irect.y0 ;
4111+ size_t n = (size_t ) pm->n ;
4112+ size_t substride = width * n;
4113+ unsigned char * s = pm->samples + stride * (irect.y0 - pm->y ) + n * (irect.x0 - pm->x );
4114+ // Cache previous pixel.
4115+ char oldpix[10 ];
4116+ assert (n < = size (oldpix));
4117+ memcpy (oldpix, s, n);
4118+ long cnt = 0 ;
4119+ for (size_t i = 0 ; i < height; i++)
4120+ {
4121+ for (size_t j = 0 ; j < substride; j += n)
4122+ {
4123+ const char * newpix = (const char *) s + j;
4124+ if (memcmp (oldpix, newpix, n))
4125+ {
4126+ /* Pixel differs from previous pixel, so update results with
4127+ last run of pixels. We get a PyObject representation of pixel
4128+ so we can look up in Python dict <rc>. */
4129+ PyObject* pixel = PyBytes_FromStringAndSize (&oldpix[0 ], n);
4130+ PyObject* c = PyDict_GetItem (rc, pixel);
4131+ if (c) cnt += PyLong_AsLong (c);
4132+ DICT_SETITEM_DROP (rc, pixel, PyLong_FromLong (cnt));
4133+ Py_DECREF (pixel);
4134+ /* Start next run of identical pixels. */
4135+ cnt = 1 ;
4136+ memcpy (oldpix, newpix, n);
4137+ }
4138+ else
4139+ {
4140+ cnt += 1 ;
4141+ }
4142+ }
4143+ s += stride;
4144+ }
4145+ /* Update results with last pixel. */
4146+ PyObject* pixel = PyBytes_FromStringAndSize (&oldpix[0 ], n);
4147+ PyObject* c = PyDict_GetItem (rc, pixel);
4148+ if (c) cnt += PyLong_AsLong (c);
4149+ DICT_SETITEM_DROP (rc, pixel, PyLong_FromLong (cnt));
4150+ Py_DECREF (pixel);
4151+ PyErr_Clear ();
4152+ return rc;
4153+ }
4154+
40984155%}
40994156
41004157/* Declarations for functions defined above. */
@@ -4224,3 +4281,5 @@ src->n must be -1, 0 or +1. If -1, <src> must have alpha and <pm> must not have
42244281alpha, and we copy the non-alpha bytes. If +1 <src> must not have alpha and
42254282<pm> must have alpha and we set <pm>'s alpha bytes all to 255.*/
42264283void pixmap_copy (fz_pixmap* pm, const fz_pixmap* src, int n);
4284+
4285+ PyObject* ll_JM_color_count (fz_pixmap *pm, PyObject *clip);
0 commit comments