def __call__(self, x: np.ndarray, y: np.ndarray | None = None) -> tuple[np.ndarray, np.ndarray | None]:
        """
        Apply pixel defence to sample `x`.

        :param x: Sample to defense with shape `(batch_size, width, height, depth)`. `x` values are expected to be in
                the data range [0, 1].
        :param y: Labels of the sample `x`. This function does not affect them in any way.
        :return: Purified sample.
        """
        # Convert into `uint8`
        original_shape = x.shape
        if self.pixel_cnn is not None:
            activations = self.pixel_cnn.get_activations(x, layer=-1, batch_size=self.batch_size)
            if isinstance(activations, np.ndarray):
                probs = activations.reshape((x.shape[0], -1, 256))
            else:
                raise ValueError("Activations are None.")
        else:
            raise ValueError("No model received for `pixel_cnn`.")

        x = x * 255
        x = x.astype("uint8")
        x = x.reshape((x.shape[0], -1))

        # Start defence one image at a time
        for i, x_i in enumerate(tqdm(x, desc="PixelDefend", disable=not self.verbose)):
            for feat_index in range(x.shape[1]):
                # Set up the search space
                f_probs = probs[i, feat_index, :]
                f_range = range(
                    int(max(x_i[feat_index] - self.eps, 0)),
                    int(min(x_i[feat_index] + self.eps, 255) + 1),
                )

                # Look in the search space
                best_prob = -1
                best_idx = -1
                for idx in f_range:
                    if f_probs[idx] > best_prob:
                        best_prob = f_probs[idx]
                        best_idx = idx

                # Update result
                x_i[feat_index] = best_idx

            # Update in batch
            x[i] = x_i

        # Convert to old dtype
        x = x / 255.0
        x = x.astype(ART_NUMPY_DTYPE).reshape(original_shape)

        # Clip to clip_values
        x = np.clip(x, self.clip_values[0], self.clip_values[1])

        return x, y

        Apply pixel defence to sample `x`.

        :param x: Sample to defense with shape `(batch_size, width, height, depth)`. `x` values are expected to be in
                the data range [0, 1].
        :param y: Labels of the sample `x`. This function does not affect them in any way.
        :return: Purified sample.
        
art/defences/preprocessor/pixel_defend.py